ここから本文です

この知恵ノートを「知恵コレクション」に追加しました。

追加した知恵ノートはMy知恵袋の「知恵コレクション」ページで確認できます。

知恵コレクション」に登録済みです。

再登録しました。

追加に失敗しました。

ノートに戻り、もう一度やり直してください。

すでに1,000件のノートが登録されています。

新しく追加したい場合は、My知恵袋の「知恵コレクション」ページで登録されているノートを削除してください。

追加できませんでした。

ノートは削除されました。

DVDStylerを使って17タイトル以上でシャッフル再生を行う方法+α

ライターさん(最終更新日時:2014/2/9)投稿日:

  • ナイス!:

    0

  • 閲覧数:1516

印刷用のページを表示する

はじめに

比較的タイトル数の多いDVDを作成する機会があり、できればシャッフル(ランダム)再生機能を付けたいと考えていたところ、こちらの記事を目にしたので参考に作ってみました。以下はその時の内容を備忘録として記したものを公開に合わせて加筆・訂正したものです。

用語の定義

まず最初に、シャッフル再生とランダム再生という用語が曖昧なので、ここでは次のように定めます。

ランダム再生:無作為にタイトルを再生する。再生数は考慮しない。
シャッフル再生:各タイトルを順不同で必ず1回再生する。再生数=タイトル数。

  • 例えばタイトル数が4のDVDがあった場合、ランダム再生では3-2-2-1-4-2-3...のようにダブって再生されるタイトルもあり、この時再生数を限定した場合(例えばタイトル数)は、再生されないタイトルもある。
  • シャッフル再生では1-4-2-3や2-4-3-1などのように、再生数は必ずタイトル数と一致し、かつ各タイトルは必ず1回だけ再生される。なので再生されないタイトルはない。

仕様

次に大まかな仕様ですが、ここでは以下のようなメニュー構成を持つDVDを作成しようとしています。

  • DVDをプレイするとまずメインメニューが表示される
  • メインメニューには、全てを再生・タイトル選択・ランダム再生・シャッフル再生のボタンがあり、該当ボタンクリックでそれぞれの再生方法で再生される
  • 全てを再生:1タイトル目から順番にタイトルを再生し最後のタイトル再生後メインメニューに戻る
  • タイトル選択:各タイトルのサムネイルを表示したタイトル選択メニューに飛ぶ。タイトル選択メニューでタイトルがクリックされると該当タイトルが再生され、再生終了後タイトル選択メニューに戻る。この時タイトル選択画面が複数ページある場合は、当該タイトルが表示されているタイトル選択画面に戻る。
  • ランダム再生無作為に各タイトルを再生する、プレイヤーの操作で停止または意図的にメインメニューに戻らない限り延々と再生し続ける
  • シャッフル再生:上述の定義通り各タイトルを必ず1回だけ順不同で再生し最後のタイトル再生後メインメニューに戻る
このうち最初の2つの再生方法はDVDStylerのテンプレートで簡単に実現できますが、下2つを実装しようとしたり、タイトル選択画面が複数になったりするとテンプレートから変更しなければならない部分が出てきます。

今回実際作成したDVDは、タイトル数は36タイトルでタイトル選択画面は1ページ9タイトルのサムネイルが表示され、4ページ構成で次頁/前頁/メインに戻ることができ、メインメニューからランダム再生シャッフル再生ができるというものです。

作り方

まず土台としてDVDStylerのテンプレートを利用します。ここではタイトル数が多いのでテンプレートの[基本]の4つ目=タイトル選択画面のサムネイルが3x3の9個あるモノを選択します。

注意

  • DVDStylerのテンプレートは文字化けしていることが多いとおもうので、この時点でフォント指定を日本語フォントにして文字化けを解消しておいた方が、後でコピーした場合などに楽です。
 次にタイトル選択メニュー(メニュー2)を3ページ分複製(合計4ページ)し、予め用意してある素材(動画等)をサムネイルの空欄部分にドラッグ&ドロップで全て登録します。

ヒント

  • 全てを再生した場合は、この時登録した順で再生されます。
素材を登録し終わったら、各タイトル選択メニュー(メニュー2~5)のプロパティ画面で、リンクボタン(前へ・次へ・戻る)の飛び先を適宜指定します。但し戻るボタンのようにメニュー1(メインメニュー)にジャンプするボタンだけは、ジャンプ先をカスタム設定にして、g0=0;を先頭に追加(再生モードフラグの初期化)します。
g0=0; jump menu 1;
その他の、タイトル選択メニューを相互に行き来するナビゲーションボタンは、プロパティ画面のジャンプ先で表示されるプルダウンメニューから選択します。

次にVMメニューを3個追加し(右クリック>追加>ビデオマネージャーメニュー)、次のように設定します。

<VMメニュー1>
[最後に選んだボタンを記憶する]:チェックなし
[タイトル]:チェック
プレコマンド:
jump titleset 1 menu;
<VMメニュー2(ランダム再生)>
[最後に選んだボタンを記憶する]:チェックなし
[タイトル]:チェックなし
プレコマンド:
g0=1; g1=random(36); if(g1==1){jump title 1;} if(g1==2){jump title 2;} if(g1==3){jump title 3;} if(g1==4){jump title 4;} if(g1==5){jump title 5;} if(g1==6){jump title 6;} if(g1==7){jump title 7;} if(g1==8){jump title 8;} if(g1==9){jump title 9;} if(g1==10){jump title 10;} if(g1==11){jump title 11;} if(g1==12){jump title 12;} if(g1==13){jump title 13;} if(g1==14){jump title 14;} if(g1==15){jump title 15;} if(g1==16){jump title 16;} if(g1==17){jump title 17;} if(g1==18){jump title 18;} if(g1==19){jump title 19;} if(g1==20){jump title 20;} if(g1==21){jump title 21;} if(g1==22){jump title 22;} if(g1==23){jump title 23;} if(g1==24){jump title 24;} if(g1==25){jump title 25;} if(g1==26){jump title 26;} if(g1==27){jump title 27;} if(g1==28){jump title 28;} if(g1==29){jump title 29;} if(g1==30){jump title 30;} if(g1==31){jump title 31;} if(g1==32){jump title 32;} if(g1==33){jump title 33;} if(g1==34){jump title 34;} if(g1==35){jump title 35;} if(g1==36){jump title 36;}
<VMメニュー3(シャッフル再生)>
[最後に選んだボタンを記憶する]:チェックなし
[タイトル]:チェックなし
プレコマンド:
g0=2; if(g3==0){jump titleset 1 menu;} RND: g1=random(36); g4=g1-1; OVR: if(g4>=16){g4-=16; goto OVR;} g5=1; POW: if(g4>0){g5*=2; g4-=1; goto POW;} if(g1<=16){if(g6&g5!=0){goto RND;} g6|=g5; if(g1==1){jump title 1;} if(g1==2){jump title 2;} if(g1==3){jump title 3;} if(g1==4){jump title 4;} if(g1==5){jump title 5;} if(g1==6){jump title 6;} if(g1==7){jump title 7;} if(g1==8){jump title 8;} if(g1==9){jump title 9;} if(g1==10){jump title 10;} if(g1==11){jump title 11;} if(g1==12){jump title 12;} if(g1==13){jump title 13;} if(g1==14){jump title 14;} if(g1==15){jump title 15;} if(g1==16){jump title 16;}} if(g1<=32){if(g7&g5!=0){goto RND;} g7|=g5; if(g1==17){jump title 17;} if(g1==18){jump title 18;} if(g1==19){jump title 19;} if(g1==20){jump title 20;} if(g1==21){jump title 21;} if(g1==22){jump title 22;} if(g1==23){jump title 23;} if(g1==24){jump title 24;} if(g1==25){jump title 25;} if(g1==26){jump title 26;} if(g1==27){jump title 27;} if(g1==28){jump title 28;} if(g1==29){jump title 29;} if(g1==30){jump title 30;} if(g1==31){jump title 31;} if(g1==32){jump title 32;}} if(g1<=48){if(g8&g5!=0){goto RND;} g8|=g5; if(g1==33){jump title 33;} if(g1==34){jump title 34;} if(g1==35){jump title 35;} if(g1==36){jump title 36;}}
さらにメインメニューその他を以下のように設定します。

<メニュー1>
[ルート]:チェック
プレコマンド:
if(g0==3) {if(g2==2){jump menu 2;} if(g2==3){jump menu 3;} if(g2==4){jump menu 4;} if(g2==5){jump menu 5;}} else {g0=0;}
メニュー1を表示した状態で、既存のボタンをコピー&ペーストし、新たにランダム再生・シャッフル再生2個のボタンを作成・配置します。

ランダム再生ボタン

[全タイトルを再生]:チェックなし
[ジャンプ先]:VMメニュー2

シャッフル再生ボタン
[全タイトルを再生]:チェックなし
[ジャンプ先]:カスタムをチェック
g3=36; g6=0; g7=0; g8=0; jump vmgm menu 3;
<メニュー2~5>
[最後に選んだボタンを記憶する]:チェックなし
プレコマンド:
g0=3; g2=x;
※xはメニュー番号

<各タイトルのポストコマンド>
if(g0==1){call vmgm menu 2;} else {if(g0==2){g3-=1; call vmgm menu 3;} else {call vmgm menu 1;}}

注意

  • 動画素材をドラッグ&ドロップした時点で、DVDStylerの設定によってはcall last menu;などが入力されていることがありますが、これは消して上のコマンドを入力します。
以上設定が完了したら、ファイル>DVD書込み...を選択してDVDを作成します。

製作&再生環境
OS: WindowsXP SP3
DVDStyler 2.6.1
ISO virtual mount: DAEMON Tools 3.47
Player: Media Player Classic 6.4.9.0 (JPN) R3 Lite
Writing: ImgBurn v2.5.8.0


解説

構成

まず大まかな構造ですが、テンプレートの初期状態ではメインメニュータイトル選択メニューがあります。今回はタイトル数36タイトルなので1ペー ジ9タイトル表示で4ページ分のタイトル選択メニュー(メニュー2~5)を追加で作成しています。さらに計3つのビデオマネージャーメニュー(VMメニュー)を 追加しています。

menu.jpg

動作

このDVDがどのような動作をするかというと、まずプレイされると最初にVMメニュー1に行きますが、プレコマンドで指定したとおりすぐにメニュー1(メインメニュー)に飛びます。メニュー1はなんらかのアクションがない限り表示され続けます。

メニュー1のプレコマンドでは基本的にはg0(再生モードフラグ)を初期化(g0=0)しています。

ここでランダム再生ボタンをクリックすると、VMメニュー2に飛びます。ここでは上の通りg0をランダム再生(g0=1)にセットしランダムに各タイトルに 飛びます。各タイトルが再生し終わるとポストコマンドで指定したように、g0が1なので再びVMメニュー2に飛びます。ランダム再生はプレイヤー側で意図的にメインメニューに戻ったり停止させない限りこの動作を延々続けます。

シャッフル再生ボタン
をクリックした場合もほとんど同様ですが、 飛び先はVMメニュー3になります。g0はシャッフル再生(g0=2)にセットされランダムに各タイトルに飛びます。各タイトル再生後はg0が2なので再びVMメニュー3に飛びますが、この時g3を減じることで再生数をカウントしています。VMメニュー3のプレコマンドの冒頭で再生数を判定し全タイトル再生済み(g3==0)の場合はメニュー1に飛びます。それ以外の場合はタイトル再生~VMメニュー3を繰り返します。

タイトル選択メニューが選択された場合は、それぞれのメニューのプレコマンドでタイトル選択再生(g0=3)と自身のメニュー番号をg2にセットし、選択されたタイトルを再生します。タイトル再生後は一旦VMメニュー1に飛びVMメニュー1のプレコマンドに従ってメニュー1に飛びます。ここでメニュー1のプレコマンドで g0=3なので自動的にg2にセットされたタイトル選択メニュー(メニュー2~5)に飛びます。
  root2.jpg

グローバルレジスタ

ここでg0,g1などはグローバルレジスタ(以下GPRM)のことで、要は変数の格納場所のようなものです。GPRMは0~15までの16個あり、うち最後 の3つはDVDStylerが予約しているため、使用できるのは g0~g12の13個で、格納できる値は0~65535までだそうです。今回は以下のようにGPRMを使用しています。
GPRM意味
g0
g1
g2
g3
g4
g5
g6, g7, g8
再生モード(どのメニューから飛んできたか)
ランダムに選択されたタイトル番号
タイトル選択メニュー番号
タイトル数
2を乗じる回数カウンタ
タイトル番号から割り出されるビットフラグ定数(1,2,4,8,16...32768)
再生済みタイトルステータス

ヒント

  • g0~g3までは上の大まかな動作説明で出てきています。g4以降はシャッフル再生でのみ使用しています。

ランダム再生(VMメニュー2>プレコマンド)

次にランダム再生≒VMメニュー2のプレコマンドの解説です。ランダム再生では上述のようにプレイヤー側で意図的に停止・メインメニューに戻るなどのアクションを起こさない限り、ランダムに選ばれたタイトルを延々と再生し続けます。

このため逆にプログラムはいたって単純で、g0(=再生モードを示すGPRM)をセットした後
g0=1;
ランダム関数でタイトル数と同数の無作為な値を得て、一旦g1に格納し、
g1=random(36);
あとは単純にそのタイトルに飛んでいるだけです。
if(g1==1){jump title 1;}
      :
if(g1==36){jump title 36;}

ポイント

  • 最後の部分はjump title g1のように書ければ1行で済むところですが、どうやらそうはいかないようなので、g1の値をチェックし飛ぶ命令を文字通り羅列しています。これは特にプログラムに慣れている人ほど冗長に感じるかも知れませんが、おそらくどうしようもない部分ですので、次に説明するシャッフルの場合でもこのような書き方は変わりません。ですので一見長いコードに見えますがほとんどがこのjump命令ですので、実質3行の単純なコマンドです。

シャッフル再生

次に本題のシャッフル再生ですが、基本的な流れとしてはランダム再生と違いありません。ですが再生数が限定されている(再生数=タイトル数)ことと、各タイトルが再生済かどうかを記憶しておかなければならないため、若干複雑になっています。

まず再生数のカウントですが、メニュー1(メインメニュー)のシャッフル再生ボタンで、作成するDVDのタイトル数に合わせて初期化します。※この例では36
g3=36;
シャッフル再生ボタンはシャッフル再生開始時に1回押されるだけなので、これら以外のGPRMの初期化も全てここで行っています。
g6=0; g7=0; g8=0;
実際の再生数のカウント各タイトルのポストコマンドで行います。
if(g0==2){g3-=1; call vmgm menu 3;}
そしてVMメニュー3プレコマンドの冒頭部分でその時点での再生数を判定し、0になった時点でメニュー1に戻りシャッフル再生が終了します。
if(g3==0){jump titleset 1 menu;}

ヒント

  • 今回はシャッフル再生でのみ再生数をカウントしていますが、この部分のロジックをランダム再生に組み込むことで、ランダム再生でもタイトル数(または任意の回数)に限定した再生を行うことも可能です。
次にタイトルが再生済かどうかのチェック部分ですが、これは参考記事と同じようにビットフラグを利用します。ここで問題なのはGPRMの長さ(容量?)です。GPRMに格納できる値は0~65535までなので、ビットを立てていくと17個目で65536(=2の16乗)となり溢れてしまうため、1個のGPRMでチェックできるタイトル数は16タイトルとなります。

そこでGPRMを複数個使い17タイトル以上にも対応させようとおもいます。

ヒント

  • ビットフラグに関してはここでは詳しくは述べませんが、簡単にいうと2の乗数(1,2,4,8,16~)を任意の変数(ここではGPRM)と&演算やOR演算することで、1個の変数で複数(この場合は上の通りGPRMの容量?が65535なので16個)の状態を記憶しておくことができるというものです。
今回の場合記憶すべき状態とはタイトルが再生済みかどうかということなので、タイトル番号とフラグ番号?を関連付けて定義しなければなりません。通常なんらかの状態をビットフラグで管理しようとする場合は、事前に定数で定義したりするものですが、ここでは単純にタイトル番号ですので以下のようにプログラムで計算してしまいます。

注意

  • 話を簡単にするためにさしあたって16タイトル(GPRMは1個使用)の場合を例にします。
RND:
g1=random(16);
g4=g1-1;
 ※中略(後で追加)
g5=1;
POW:
if(g4>0){g5*=2; g4-=1; goto POW;}
ランダムに取得したタイトル番号(g1)から1引いているのは、2を乗じる回数(g4)が0の場合を作りたいからで、これによりg4は0~15の範囲になります。そして実際にフラグ定数(g5)を求めている部分では、初期値として1を置き、カウンタが0より大きい場合はカウンタ回数分2を掛けているだけです。RND:ラベルはフラグが立っていた場合にもう一度ランダムから始めるためのラベルです。

これをランダムではなく順番に実行?すると以下のようにタイトル番号に対応したフラグの値が得られます。
タイトル番号
フラグの値
2進数表記
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
1
2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
16384
32768
0000 0000 0000 0001
0000 0000 0000 0010
0000 0000 0000 0100
0000 0000 0000 1000
0000 0000 0001 0000
0000 0000 0010 0000
0000 0000 0100 0000
0000 0000 1000 0000
0000 0001 0000 0000
0000 0010 0000 0000
0000 0100 0000 0000
0000 1000 0000 0000
0001 0000 0000 0000
0010 0000 0000 0000
0100 0000 0000 0000
1000 0000 0000 0000
実際はこの16個のうちのどれか一つがランダムに選ばれることになるわけですが、上の通り17タイトル以上はGPRMに格納できなくなるので、その場合はGPRMが複数必要になります。

次にここで得られた値を予め決めておいた判定用のGPRMと照合した上で、ビットが立っていなければ立ててその後適宜タイトルにジャンプします。
if(g6&g5!=0){goto RND;}  //判定、フラグが立っていればやり直し
g6|=g5;            //フラグを立てる
if(g1==1){jump title 1;}  //指定タイトルにジャンプ(以下同)
if(g1==2){jump title 2;}
     :
     :
if(g1==16){jump title 16;}
ここでg6が実際タイトルが再生済みかどうかの判定用GPRMになります。16タイトルまでならこれで完成ですが、次に17タイトル以上に対応できるようなコードを考えます。

まずフラグの値をタイトル番号から求める部分ですが、タイトル番号が17以上の場合は別のGPRMを使用することにし、かつフラグの値が65535(2の16乗-1)を超えないようにします。

フラグの値は上述のようにタイトル番号から2を掛ける回数を求めているので、上のコードの※中略(後で追加)の部分に新たに次のようなコードを記述します。
OVR:
if(g4>=16){g4-=16; goto OVR;}
見ての通りひたすら16を引いているだけですが、このコードはカウンタ(g4)の値を0~15に丸める?ことで、フラグの値が65535以内に収まるようにするためのものです。

あとはタイトル番号によって使うGPRMを変えてビットフラグを確認すればよいだけですので、次のようなコードになります。
if(g1<=16){
  if(g6&g5!=0){goto START;}
  g6|=g5;
  if(g1==1){jump title 1;}
      :
  if(g1==16){jump title 16;}
}
if(g1<=32){
  if(g7&g5!=0){goto START;}
  g7|=g5;
  if(g1==17){jump title 17;}
      :
  if(g1==32){jump title 32;}
}
if(g1<=48){
  if(g8&g5!=0){goto START;}
  g8|=g5;
  if(g1==33){jump title 33;}
      :
  if(g1==36){jump title 36;}
}

最初の16タイトルに使うGPRMはg6で、次の16タイトル(17~32タイトル)はg7という新たなGPRMを使います。さらに次の16タイトル(33~48)ではg8を使う~というように16タイトルづつ使用するGPRMを増やしていけば、理論的には何タイトルでも対応できるはずです。

しかしながらGPRMの個数には限りがあり、プレコマンドで入力できるコマンド数も上限が128とのことなので、今回のようにGPRM3つ分(最大48タイトル)あたりが限界なのではないでしょうか?

以上で解説を終了します。最後になりましたが参考記事を書かれた方にこの場を借りてお礼申し上げます。この知恵ノートがなければ、そもそもシャッフル再生を作ろうとはおもわなかったでしょうし、再生済タイトルをビットフラグで管理する方法など大変参考になりました。ありがとうございました。
このノートについて質問する

このノートについてライターの方に質問できます。

※ライターの方から必ず回答をいただけるとは限りません

※別ウィンドウで開きます

この知恵ノートのライター

グレード

グレード知恵ノートのグレード:1-2

seeauliさん

ピックアップ

【iPhone】修理交換の申込方法...
 ※追記※2015/1/30現在iPhone6及び6+が発売されたのを受け、情...
耳鼻科の先生に聞いた、しゃっ...
  皆さん、しゃっくりってわずらわしいですよね  ある時急に...
厄年について——意外と知られて...
厄年とは何か厄年とは文字どおり災厄に遭いやすいといわれる...
本文はここまでです このページの先頭へ