首页 > 学院 > 编程设计 > 正文

脚本的DVD开发

2020-01-31 16:14:08
字体:
来源:转载
供稿:网友
好像包含表格不能发表,只有先拷贝到记事本里面才可以,所以格式都丢了,不好意思

这个也是很久以前的东西了,不准确的地方还请大家见谅.哎,我的一本书没有被出版,就放到这里吧(出版社的人说看不懂,呵呵,我都快晕死了)

基于脚本的dvd应用程序
在网络发展神速的今天,软件业越来越注重基于网络的应用,下来我们就探讨一下基于web的程序编写。这里主要讲述使用mswebdvd控件进行dvd应用程序的开发过程。 
插入MSWebDVD对象
MSWebDVD对象可以处理所有的dvd导航命令,并可以在web页面上显示视频。这将比原来的处理过程简单很多,简单的插入代码示例如下:
<OBJECT CLASSID=clsid:38EE5CEE-4B62-11D3-854F-00A0C9C898E7 ID=DVD 
    STYLE="height:369px; width:740px">
<PARAM NAME="BackColor" VALUE="1048592">
<PARAM NAME="EnableResetOnStop" VALUE="-1">
<PARAM NAME="ColorKey" VALUE="1048592">
</OBJECT>
允许用户处理dvd命令
若允许用户控制dvd播放器,则需要提供一个用户界面来引导用户,比如“播放”,“停止”按钮。下面的代码就展示了怎样将一个html的按钮和mswebdvd对象关联起来。
<INPUT ID=button1 NAME="button1" TYPE=button VALUE="Play" onClick=´Play();´>
<INPUT ID=button2 NAME="button2" TYPE=button VALUE="Pause" onClick=´Pause();´>

<SCRIPT LANGUAGE="JScript">
function Play(){
  DVD.Play(); 
}

function Pause(){
  DVD.Pause();
}

</SCRIPT>
用dvd菜单进行工作
当用户点击屏幕的按钮时,Mswebdvd会自动的处理菜单命令。应用程序不需要处理任何事情来实现对鼠标的支持。但是应用程序可以不考虑这个自动处理过程。如果你对定制鼠标工作十分感兴趣,那么你可以使用mswebdvd关联菜单的方法,比如SelectAndActivateButton, GetButtonAtPosition。要想彻底的禁止鼠标的自动化动作处理,那么设置DisableAutoMouseProcessing属性为真就可以了。
音频和子图流
一个dvd碟片可以处理8路音频流,从07,每个音频流又包含了6个独立的通道。只有这些流在能在任何时间被激活。对于子图来说,有32个流是有效的,从0-31。碟片通常制作成默认的音频和子图流,但一个应用程序允许用户看到所有有效的流数据,然后选择一种他们喜欢的语言。基本步骤的处理和音频与子图流相同。
1. 决定指定标题的有效流的数量。
2. 重新检测每个流的属性。
3. 从本地标识中返回语言代码,然后创建人们可读的字符串。
4. 添加“选择”对话框,或者别的用户界面来允许用户选择首选的数据流。
(注意音频和子图流标记是从0开始的,然而别的大部分都是从1开始)
强制父级管理层
在dvd碟片中通常任何的标题或者标题的一部分会被标记一个父级管理层(PML)
从1到8,8级是限制最多的,1级是限制最少的等级。有一种想法提供了一种装置来防止小孩看成人的内容,但每个国家的特殊性决定了他们将不会一样。在美国和加拿大是一种标准,和别的国家就不太一样。
MSWebDVD对象默认状态是忽略pmls的。对于应用程序来讲,它将会通报pml标记,这样必需调用NotifyParentalLevels(true)。当在碟片上碰到pml信息的时候,MSWebDVD将会通知你的应用程序。为了强制pmls,你的应用程序必需实现一些逻辑口令来将用户和不同的级别联系在一起,响应EC_DVD_PARENTAL_LEVEL_CHANGE事件来允许或者禁止访问。
保存和恢复书签
书签是一个MSWebDVD对象内部的数据结构,它可以被用来创建一个当前用户任务的快照,包含内容比如是当前碟片位置的信息,私人的父层管理级别,选择音频和子图流等等。这个意思是让用户可以保存当前的dvd状态可以下次接着从这个状态中继续观看。
SaveBookmark方法允许用户保存他们碟片的位置,RestoreBookmark方法则允许同一个用户可以接着上次储存的位置接着观看。
一次只能储存一个书签。如果你调用了两次SaveBookmark,那么第一次的书签将会被第二次的书签覆盖。书签对于计算机来说是特别的。在不同的计算机中运行同样的html页面,然后调用RestoreBookmark将会恢复最近的那次存储的书签,或者返回一个以前没有存储的标志错误。
处理dvd通报事件
当某种事件发生了的时候,MSWebDVD对象会向应用程序发送一个特定的通报事件,例如当DVD的域改变了,当遇到一个新的父层管理等等。事件参数可以获得与事件有关的附加信息。错误信息和警告信息都是通过这种方法进行发送的。为了扑获到变化的dvd事件通报,在html SCRIPT中加入以下代码。
<SCRIPT LANGUAGE="JScript" FOR=DVD EVENT="DVDNotify(EventCode, Param1, Param2)">
    ProcessDVDEvent(EventCode, Param1, Param2)
</SCRIPT>
然后,在脚本中,定义事件代码和ProcessDVDEvent函数,下面的代码将展示它的用法。(你可以给你的事件处理函数任何的名称)
<SCRIPT LANGUAGE="JScript">

// DVD event codes are valued 257 through 283
var EC_DVDBASE = 256;

var EC_DVD_DOMAIN_CHANGE = (EC_DVDBASE + 1);
var EC_DVD_TITLE_CHANGE = (EC_DVDBASE + 2);
var EC_DVD_CHAPTER_START = (EC_DVDBASE + 3);
var EC_DVD_AUDIO_STREAM_CHANGE = (EC_DVDBASE + 4);
var EC_DVD_SUBPICTURE_STREAM_CHANGE = (EC_DVDBASE + 5);
var EC_DVD_ANGLE_CHANGE  = (EC_DVDBASE + 6);
var EC_DVD_BUTTON_CHANGE = (EC_DVDBASE + 7);
var EC_DVD_VALID_UOPS_CHANGE = (EC_DVDBASE + 8);
var EC_DVD_STILL_ON  = (EC_DVDBASE + 9);
var EC_DVD_STILL_OFF  = (EC_DVDBASE + 10);
var EC_DVD_CURRENT_TIME  = (EC_DVDBASE + 11); // not used by MSWebDVD
var EC_DVD_ERROR  = (EC_DVDBASE + 12);
var EC_DVD_WARNING  = (EC_DVDBASE + 13);
var EC_DVD_CHAPTER_AUTOSTOP  = (EC_DVDBASE + 14);
var EC_DVD_NO_FP_PGC  = (EC_DVDBASE + 15);
var EC_DVD_PLAYBACK_RATE_CHANGE  = (EC_DVDBASE + 16);
var EC_DVD_PARENTAL_LEVEL_CHANGE  = (EC_DVDBASE + 17);
var EC_DVD_PLAYBACK_STOPPED  = (EC_DVDBASE + 18);
var EC_DVD_ANGLES_AVAILABLE  = (EC_DVDBASE + 19);
var EC_DVD_PLAYPERIOD_AUTOSTOP  = (EC_DVDBASE + 20);
var EC_DVD_BUTTON_AUTO_ACTIVATED  = (EC_DVDBASE + 21);
var EC_DVD_CMD_START  = (EC_DVDBASE + 22);            // not used by MSWebDVD
var EC_DVD_CMD_END = (EC_DVDBASE + 23);               // not used by MSWebDVD
var EC_DVD_DISC_EJECTED  = (EC_DVDBASE + 24);
var EC_DVD_DISC_INSERTED  = (EC_DVDBASE + 25);
var EC_DVD_CURRENT_HMSF_TIME  = (EC_DVDBASE + 26);
var EC_DVD_KARAOKE_MODE  = (EC_DVDBASE + 27);

var nCurDomain;
var nCurParentalLevel;

function ProcessDVDEvent(EventCode, Param1, Param2)
{
    switch (EventCode)
    {
    case EC_DVD_DOMAIN_CHANGE:
        nCurDomain = Param1;
        // do something
        break;
    case EC_DVD_PARENTAL_LEVEL_CHANGE:
        nCurParentalLevel = Param1;
        // do something
        break;

    // handle any other events you are interested in

    default:
        break;
    }
}
</SCRIPT>
处理用户的事件通告
当特定的用户操作被允许或者被禁止的时候,MSWebDVD对象发送一个uop通报信息给应用程序。每个用户操作都有自己的事件,但它们都是一个Boolean量,仅仅用来标识操作现在被允许或者被禁止。
对于每个你希望处理的事件,指定的事件处理者展示了一些代码,读者可以参阅。
<SCRIPT LANGUAGE="JScript" FOR=DVD EVENT="PlayForwards(bEnabled)">
    PlayForwardsEventHandler(bEnabled)
</SCRIPT>
Now define your handler method to respond appropriately to the event. Assume that the "button_Play" variable here is the id attribute of the "Play" button in your application. 
function PlayForwardsEventHander(bEnabled)
{
  if(bEnabled == true)
    button_Play.disabled = false;
  else
    button_Play.disabled = true;
}
同步满足html要求的视频
通过处理碟片的事件编码事件,一个web应用程序就可以同步满足html的视频了。例如,你可以使图像和文字在这个页面视频上的指定点进行变化。下面的代码展示了一种通过时间编码事件来同步jscipt函数的调用。
//DVDTriggerPoints array holds frame count for each trigger. Must be in ascending order.
//Use timecode2frames() to convert timecodes (hh:mm:ss:ff) to total number of frames.

var DVDTriggerPoints = new Array(
  timecode2frames("01:15:24:00"), 
  timecode2frames("01:23:02:00"));

//DVDTriggerProcs array holds functions to be called at each trigger point defined in DVDTimePoints.
var DVDTriggerProcs = new Array(
  "showDogPic();",
  "showCatPic();");

//DVDTriggerIndex keeps track of current trigger (it indexes DVDTriggerPoints and DVDTriggerProcs).
var DVDTriggerIndex = 0;

//Handle DVD Events
function ProcessDVDEvent(EventCode, Param1, Param2) {
  switch (EventCode) {
     case EC_DVD_CURRENT_HMSF_TIME:
          if(MSWebDVD.CurrentDomain == 4) {  //Don't bother checking unless disc is playing.
             if (DVDTriggerIndex < DVDTimePoints.length) {  //Are there trigger points left to check?
                currentDVDTime = (MSWebDVD.DVDTimeCode2bstr(Param1));
                 if (timecode2frames(currentDVDTime)>= DVDTriggerPoints[DVDTimeIndex]) {
                     // if trigger point has passed, execute the associated function
                    eval(DVDTriggerProcs[DVDTimeIndex++]);
                 }
             }
          }
       break;

       // handle other events 
   }
}

function timecode2frames(timeCode) {

   if (timeCode != "undefined") {
       return timeCode.substring(0,2)*108000
       + timeCode.substring(3,5)*1800
       + timeCode.substring(6,8)*30
       + timeCode.substring(9,11);
   } else {
       return 0;
   }
}
用LCIDs进行工作
LCID,或者可以叫做“locale identifer”,它是一个32位的数据类型,它是为了帮助我们鉴定不同的地区区码语言。这些值的其中一项就是“主语言标识”,这可以用来鉴定基本的区域语言。例如,英语,西班牙语等。
MSWebDVD要求一个完整有效的LCID作为下面两种方法的输入参数: SelectDefaultAudioLanguage和SelectDefaultSubpictureLanguage。这些可以是任何可被Windows识别的有效LCID,甚至也可以不被Windows识别。(主机不必一定支持本地机的字体、键盘映射等)下面列表写出了一些通用LCIDs以及Windows默认态不识别但对MSWebDVD有效的非通用LCIDs。该表不是完整的LCIDs列表。
一些有效的 LCIDs
Afrikaans 0x0436 Albanian 0x041c Arabic (Algeria) 0x1401
Arabic (Bahrain) 0x3c01 Arabic (Egypt) 0x0c01 Arabic (Iraq) 0x0801
Arabic (Jordan) 0x2c01 Arabic (Kuwait) 0x3401 Arabic (Lebanon) 0x3001
Arabic (Libya) 0x1001 Arabic (Morocco) 0x1801 Arabic (Oman) 0x2001
Arabic (Qatar) 0x4001 Arabic (Saudi Arabia) 0x0401 Arabic (Syria) 0x2801
Arabic (Tunisia) 0x1c01 Arabic (U.A.E.) 0x3801 Arabic (Yemen) 0x2401
Basque 0x042d Belarusian 0x0423 Bulgarian 0x0402
Catalan 0x0403 Chinese (Hong Kong) 0x0c04 Chinese (PRC) 0x0804
Chinese (Singapore) 0x1004 Chinese (Taiwan) 0x0404 Croatian 0x041a
Czech 0x0405 Danish 0x0406 Dutch (Belgian) 0x0813
Dutch (Standard) 0x0413 English (Australian) 0x0c09 English (Belize) 0x2809
English (Canadian) 0x1009 English (Caribbean) 0x2409 English (Ireland) 0x1809
English (Jamaica) 0x2009 English (New Zealand) 0x1409 English (South Africa) 0x1c09
English (Trinidad) 0x2c09 English (United Kingdom) 0x0809 English (United States) 0x0409
Estonian 0x0425 Faeroese 0x0438 Farsi 0x0429
Finnish 0x040b French (Belgian) 0x080c French (Canadian) 0x0c0c
French (Luxembourg) 0x140c French (Standard) 0x040c French (Swiss) 0x100c
German (Austrian) 0x0c07 German (Liechtenstein) 0x1407 German (Luxembourg) 0x1007
German (Standard) 0x0407 German (Swiss) 0x0807 Greek 0x0408
Hebrew 0x040d Hungarian 0x040e Icelandic 0x040f
Indonesian 0x0421 Italian (Standard) 0x0410 Italian (Swiss) 0x0810
Japanese 0x0411 Korean 0x0412 Korean (Johab) 0x0812
Latvian 0x0426 Lithuanian 0x0427 Malay (Malaysian) 0x043e
Malay (Brunei) 0x083e Norwegian (Bokmal) 0x0414 Norwegian (Nynorsk) 0x0814
Polish 0x0415 Portuguese (Brazilian) 0x0416 Portuguese (Standard) 0x0816
Romanian 0x0418 Russian 0x0419 Serbian (Cyrillic) 0x0c1a
Serbian (Latin) 0x081a Slovak 0x041b Slovenian 0x0424
Spanish (Argentina) 0x2c0a Spanish (Bolivia) 0x400a Spanish (Chile) 0x340a
Spanish (Colombia) 0x240a Spanish (Costa Rica) 0x140a Spanish (Dominican Republic) 0x1c0a
Spanish (Ecuador) 0x300a Spanish (El Salvador) 0x440a Spanish (Guatemala) 0x100a
Spanish (Honduras) 0x480a Spanish (Mexican) 0x080a Spanish (Modern Sort) 0x0c0a
Spanish (Nicaragua) 0x4c0a Spanish (Panama) 0x180a Spanish (Paraguay) 0x3c0a
Spanish (Peru) 0x280a Spanish (Puerto Rico) 0x500a Spanish (Traditional Sort) 0x040a
Spanish (Uruguay) 0x380a Spanish (Venezuela) 0x200a Swahili 0x0441
Swedish 0x041d Swedish (Finland) 0x081d Thai 0x041e
Turkish 0x041f Ukrainian 0x0422    
一些MSWebDVD方法和属性返回的LCID可以指定那一个标识在音轨或者字幕上是有效的。为了使用这个信息,你的应用程序将需要从返回LCID中选择主语言标识。为了达到这个目的,我们可以将iLCID和0x3ff进行按位的与操作。以下代码摘录的演示了这种实现过程。(主语言标识中包含了LCID中的至少10位标记)
iPrimaryLang = iLCID & 0x3FF;
为了从主语言标识中获得人们可读的字符串,调用GetLangFromLangID,代码如下:
sLanguage = DVD.GetLangFromLangID(iPrimaryLang);
下面的列表展示了LCID中的主语言标识。
Some Valid Primary Language IDs
Afrikaans 0x36 Albanian 0x1c Arabic 0x01 Basque 0x2d
Belarusian 0x23 Bulgarian 0x02 Catalan 0x03 Chinese 0x04
Croatian 0x1a Czech 0x05 Danish 0x06 Dutch 0x13
English 0x09 Estonian 0x25 Faeroese 0x38 Farsi 0x29
Finnish 0x0b French 0x0c German 0x07 Greek 0x08
Hebrew 0x0d Hungarian 0x0e Icelandic 0x0f Indonesian 0x21
Italian 0x10 Japanese 0x11 Korean 0x12 Latvian 0x26
Lithuanian 0x27 Malay 0x3e Norwegian 0x14 Polish 0x15
Portuguese 0x16 Romanian 0x18 Russian 0x19 Serbian 0x1a
Slovak 0x1b Slovenian 0x24 Spanish 0x0a Swahili 0x41
Swedish 0x1d Thai 0x1e Turkish 0x1f Ukrainian 0x22
播放卡拉ok碟片
卡拉ok碟片是dvd视频碟片的一种,它有着和dvd视频碟片相同的导航结构。歌曲是按照一般节的格式存放的,节可以合成一个章,它是基本的播放单位。
对于卡拉ok碟片和普通dvd碟片的最大不同点就是音频流的区别。卡拉ok碟片是包含了所有的多通道音频,通常是Dolby AC-3。通道0和1一般包括背景音效,2到5通道包含了嗓音,合成等音频。一个卡拉ok应用程序可以控制音量和目的喇叭,可以控制混音声道。
卡拉ok的回放要求一个音频解码器,要求支持多通道的卡拉ok混音信息的解码器。解码器必需支持dvd卡拉ok属性设置(AM_PROPERTY_DVDKARAOKE)。
当DVD导航在碟片上检测到卡拉ok的内容的时候,它会自动进入卡拉ok模式,然后通知解码器上面的三个混音通道那个应该静音,直到它们被应用程序打开。
1. 决定它们的内容和混音通道数。
2. 提供一个用户接口显示通道的内容,允许用户可以在任何时间进行混音通道的开关。
Dvd的文字
Dvd 碟片,尤其是卡拉ok碟片,可能包含了一个文字信息的数据库来补充视频和音频的内容。象这样的文字,在卡拉ok碟片上有可能会包括歌曲的标题,艺术名,记录标签等等内容。这些文字可以被翻译成不同的语言。这些字符串是可选择的,碟片上不要求必需含有它们。现在它们的组织结构是通过dvd卷标的逻辑层次的近似镜像的方法实现。
有两种基本类型的字符串:结构标识和内容标识。这些类型用0x01到0x20的值是结构标识。它们是空的字符串,数字码被用来标识逻辑结构,表示内容字符串是属于那个逻辑结构的。这个结构非常符合dvd碟片内容的逻辑结构:卷标,标题,章节等等。剩下的内容标识是被用来显示到用户界面信息的字符串。
历史上, DVD 碟片上的文本串在是唯一的,这些碟片大多使用0x01 和 0x02 结构标示符以及0x30 类型内容字符串。但现在却不是如此 (1) 越来越多类型的DVD-Video碟片包含文本串(2) 为了提供对碟片内容的详尽描述这些串以更加复杂的方式组织。下例代码演示如何决定碟片上文本串语言块的数目以及检索让用户设置语言的可读串。代码中,串被添加于"TextLanguageList" HTML SELECT元素代码。 
  function GetTextLanguages()
  {
    //get the number of text blocks
    var numLangs = DVD.GetDVDTextNumberOfLanguages(); 
   var iLCID;
   var iPrimaryLang;
   var sLanguage;
   var oOption;

 for (j = 0; j < numLangs; j++)
 {
    //get the locale identifier for the language block
  iLCID = DVD.GetDVDTextLanguageLCID(j);

    //get the primary language ID from the LCID
  iPrimaryLang = iLCID & 0x3FF;

    //get the human-readable string from the primary language ID
  sLanguage = DVD.GetLangFromLangID(iPrimaryLang);

    //add it to the SELECT element on the HTML page
  oOption = document.createElement("OPTION");
  oOption.text = sLanguage;
  document.all.TextLanguageList.add(oOption);
 } 

  } //end function GetTextStrings
下列检测代码演示如何枚举串和检查文本串类型。结果在名为"myTextArea"的HTML TEXTAREA 元素中,故可以看到数字串类型如何被用于组织内容串。实程序会创建自己的数据结构来包含串或以向用户显示串。
  // iLanguage is the 0-based index for the language block
   function GetTextStrings(iLanguage)
   {

      var numStrings, stringType, j; 

      numStrings = DVD.GetDVDTextNumberOfStrings(iLanguage);

      for( j = 0; j < numStrings; j++)
      {
        stringType = DVD.GetDVDTextStringType(iLanguage, j);

        if(stringType > 0x20) //there is actually some text to read here
        {
          myTextArea.value += (stringType + ": " + DVD.GetDVDTextString(iLanguage, j) + "/n");
        }
        else // It´s a node indicating what level of the volume structure
   // the following strings will apply to
        {
          myTextArea.value += (stringType + "/n");
        }

      }
    } //end function GetTextStrings

dvd文本字符串类型
这个表格列出了dvd文本字符串类型的子集。在0x20以下的字符串都是内容字符串。大部分的歌曲名称和标题都是0x30。
结构标示符
Volume 0x01 指示串属于DVD 卷 
Title 0x02 标题 
ParentalID 0x03 指示串属于特定 父ID. 
Chapter 0x04 指示串属于章 
Cell 0x05 指示串属于单元 (电影的一个场景) 
流标示符
Audio 0x10 指示串属于音频流
Subpicture 0x11 指示串属于子图流
Angle 0x12 指示串属于角块
音频通道标示符
Channel 0x20 指示串属于音频留的一个通道
通用内容串
Name 0x30 标题名、章名、歌曲名的通用标示符
Comments 0x31 标题、章、歌曲的通用内容
标题内容串 
Series 0x38 标题、章、歌曲的附信息
Movie 0x39 电影的标题或章的附加信息
Video 0x3a 视频的标题或章的附加信息
Album 0x3b 相册的标题或章的附加信息
Song 0x3c 歌曲的标题或章的附加信息
Other 0x3f 其它的标题或章的附加信息
第二标题内容串
Series 0x40 标题、章、歌曲的附加信息
Movie 0x41 电影的标题或章的附加信息
Video 0x42 视频的标题或章的附加信息
Album 0x43 相册的标题或章的附加信息
Song 0x44 歌曲的标题或章的附加信息.
Other 0x45 其它的标题或章的附加信息
原始内容串
Series 0x48 标题、章、歌曲的附加信息
Movie 0x49 电影的标题或章的附加信息
Video 0x4a 视频的标题或章的附加信息
Album 0x4b 相册的标题或章的附加信息
Song 0x4c 歌曲的标题或章的附加信息.
Other 0x4f 其它的标题或章的附加信息
其它信息内容串
Other Scene 0x50 电影标题或章可选场景的附加信息
Other Cut 0x51 电影标题或章可选剪辑的附加信息
Other Take 0x52 电影标题或章可选画面的附加信息
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选