天天看點

vlc應用

vlc的應用之一:在指令行下的使用

   如果編譯得到沒有界面的vlc,輕按兩下運作後就沒法手動選打檔案或網絡了。在這介紹幾個vlc的指令行指令。

      1. vlc幫助 vlc --help 

or 

vlc --help --advanced       2. vlc的debug log vlc -vv --extraintf=logger     運作的log将會儲存在vlc-log.txt中。       3. vlc打開檔案 vlc -vv --extraintf=logger d:/01.avi       4. 作為伺服器通過rtp往用戶端發送ts流 vlc -vvv --extraintf=logger d:/01.avi :sout=#duplicate{dst=rtp{dst=localhost,mux=ts,port=1234}}       5. 作為用戶端接收rtp流 vlc -vv --extraintf=logger rtp://@:1234         Jeremiah最常用的就是這麼多,如果還有其他需求,參考下面幾個網址。 1.  [url]http://rogerfd.cn/?p=157[/url] 2.  [url]https://videolan.org/doc/streaming-howto/en/index.html[/url] 3.  [url]http://wiki.videolan.org/Documentation:Streaming_HowTo/Command_Line_Examples[/url] vlc的應用之二:vlc的ActiveX及cab    2009-05-14補充:8. Activex的解除安裝;9. 讓vlc自動安裝Activex ;10. 關于vlc的Activex的說明。     vlc自帶了ActiveX控件--axvlc.dll,在編譯完vlc之後的activex檔案夾下。ActiveX是個好東西, axvlc.dll 可以 随意放到任何位置, 成功注冊之後可以友善的應用在程式和網頁之中。可以參考activex檔案夾下的test.html和README.TXT。ActiveX控件的接口有第一版和第二版,第一版簡單,功能少,已經不再維護建議用第二版本,功能多一點。(參考的[1])

    vlc-0.8.6i和vlc-0.9.4的ActiveX注冊方法略有不同。

    做ActiveX的網頁測試之前需要把Internet選項-->安全-->本地Intranet的安全級别調到最低。Jeremiah的網頁測試環境是IE7,其他浏覽器未進行測試。

    1. vlc-0.8.6i的ActiveX注冊

    在E:下建立檔案夾vlc-0.8.6iActiveX,拷貝vlc-0.8.6i目錄下的plugins,libvlc.dll,activex/axvlc.dll到 vlc-0.8.6iActiveX/dlls目錄下,拷貝activex/test.html到 vlc-0.8.6iActiveX下。建立文本檔案install.bat内容如下: regsvr32 dlls/axvlc.dll     輕按兩下install.bat後會提示“dlls/axvlc.dll中的DllRegisterServer成功”。然後用打開test.html,文本框輸入MRL就可以播放了。

    2. vlc-0.9.4的ActiveX注冊

    0.9.4不光要告訴計算機vlc的axvlc.dll的位置,還要告訴系統資料庫installdir的位置,也就是libvlc.dll的位置

     在E:下建立檔案夾vlc-0.9.4ActiveX,拷貝vlc-0.9.4目錄下的plugins,libvlc.dll,libvlccore.dll,activex/axvlc.dll到 vlc-0.9.4ActiveX/dlls目錄下,拷貝activex/test.html到 vlc-0.9.4ActiveX下。建立文本檔案install.reg内容如下:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE/SOFTWARE/VideoLAN/VLC]

"InstallDir"="E://vlc-0.9.4ActiveX//dlls"     建立文本檔案install.bat内容如下:

regsvr32 dlls/axvlc.dll

regedit /s install.reg     輕按兩下install.bat後就可以用test.html進行測試了。

    3. 一點點小提示

    如果注冊成功,但是test.html播放檔案的時候會報錯說decoder modules會找不到之類資訊,那請将0.8.6i和0.9.4交替注冊,可能會解決這個問題。(Jeremiah因為這個問題搞了一天,NND)(2009-05-14補充:直接看8吧,以前這個地方寫的不大對。)

    4. 制作cab檔案

    如果要類似與test.html作個播放器伺服器,但是我們卻不能手動操縱 用戶端去下載下傳注冊vlc的ActiveX,解決方法就是自己制作cab檔案。

    (1) 到 本日志的附件 (cabsdk.rar)或者 以下位址 去下載下傳cabsdk.exe: [url]http://download.microsoft.com/download/platformsdk/cab/2.0/w98nt42kmexp/en-us/cabsdk.exe[/url]

    (2) 安裝cabsdk.exe

    (3) 将axvlc.dll及vlc的安裝檔案拷貝到cabsdk安裝路徑/BIN/ 下。Jeremiah這裡用的是vlc-0.8.6i-win32.exe。(關于如何制作vlc的安裝檔案,參考日志《windows平台下vlc編譯之二:vlc-0.8.6i的編譯》)

    (4) 在/BIN下建立文本檔案axvlc.inf,内容如下:

; Version number and signature of INF file.

;

[version]

signature="$CHICAGO$"

AdvancedINF=2.0

[Add.Code]

vlc-0.8.6i-win32.exe

axvlc.dll=axvlc.dll

[axvlc.dll]

FileVersion=0,8,6,0

clsid={9BE31822-FDAD-461B-AD51-BE1D1C159921}

RegisterServer=no

hook=nsiinstaller

[vlc-0.8.6d-win32.exe]

FileVersion=0,8,6,0

file-win32-x86=thiscab

[nsiinstaller]

run=%EXTRACT_DIR%/vlc-0.8.6i-win32.exe      注意:請根據安裝檔案的版本修改此檔案。

    (5) 指令行到BIN目錄下,執行以下指令生成cab檔案:

CABARC.EXE N axvlc.cab axvlc.inf axvlc.dll vlc-0.8.6i-win32.exe     

     5. cab檔案的使用

    html頁面下使用cab檔案可以通過以下方式:

<OBJECT classid="clsid:9BE31822-FDAD-461B-AD51-BE1D1C159921"

                codebase="your/path/of/cabfile/axvlc.cab"

                         width="640" height="480" id="vlc" events="True">

< param  name ="Src" value=""  />

< param  name ="ShowDisplay"  value ="True"  />

< param  name ="AutoLoop"  value ="False"  />

< param  name ="AutoPlay"  value ="False"  />

</OBJECT>     這樣web用戶端無須手動注冊axvlc.dll就可以使用了。

     6. 一點比較嚴重小問題

    由于vlc的安裝檔案一般是比較大,是以制作出來的cab檔案也是很大的,在網絡帶寬不是很好的時候,光下載下傳這個cab可能就很長很長時間,基本上可以說這樣的方式是行不通的。是以 我們 需要根據自己的業務需求去精簡vlc。Jeremiah将在下一篇日志介紹。

    7. C#下使用vlc的ActiveX

    vs2005建立一個windows應用程式,在左側工具箱右鍵-->選擇項-->com元件-->VideoLAN VLC ActiveX plugin v2,工具箱裡面就添加了vlc的ActiveX控件,可以在窗體裡面随便畫了。

    調用函數如下:

vlc應用

private  void button1_Click( object sender, EventArgs e)

vlc應用

{

vlc應用

         //輸入參數

vlc應用

         string parameter =  ":sout=#duplicate{dst=display} :no-overlay";

vlc應用
vlc應用

         //判斷是否正在播放

vlc應用

         if ( this.axVLCPlugin21.playlist.isPlaying)

vlc應用

        {

vlc應用

                 //如果正在播放, 則停止

vlc應用

                 this.axVLCPlugin21.playlist.stop();

vlc應用

        }

vlc應用
vlc應用

         //清空播放清單

vlc應用

         this.axVLCPlugin21.playlist.clear();

vlc應用
vlc應用

         //添加播放清單

vlc應用

         this.axVLCPlugin21.playlist.add(textBox1.Text,  null, parameter);

vlc應用
vlc應用

         //播放清單更新到新添加的播放項

vlc應用

         this.axVLCPlugin21.playlist.next();

vlc應用
vlc應用

         //播放

vlc應用

         this.axVLCPlugin21.playlist.play();

vlc應用

}     其他函數調用參考activex/README.TXT。

    Jeremiah在附件裡面提供了一個簡單的調用程式(WindowsApplication1.rar), 不過需要注意的是,在用它測試0.9.4的ActiveX,當正常播放檔案時點選X關閉視窗 産生異常,電腦會重新啟動。在主窗體的 FormClosing 事件中讓主線程睡了1000ms,并不能完全保證電腦不重新開機,是以請根據自己的情況進行本附件的調試。       8. Activex的解除安裝     解除安裝是安裝的反向操作,知道怎麼安裝,解除安裝很簡單。     vlc-0.8.6i的Activex的解除安裝:建立uninstall.bat,内容如下: regsvr32 dlls/axvlc.dll /u     vlc-0.9.4的Activex的解除安裝:建立uninstall.reg,内容如下: Windows Registry Editor Version 5.00 

[-HKEY_LOCAL_MACHINE/SOFTWARE/VideoLAN]     建立uninstall.bat,内容如下: regsvr32 dlls/axvlc.dll /u 

regedit /s uninstall.reg     輕按兩下uninstall.bat,提示dlls/axvlc.dll中的DllUnregisterServer成功。就解除安裝完畢了。        9. 讓vlc安裝的時候自動安裝Activex     4裡面提到cab包的制作及5裡面提到了cab包的使用。cab其實就是讓客戶自動下載下傳vlc的安裝檔案,然後啟動安裝。但是安裝過程中,出現這樣一步:

vlc應用

    Activex plugin預設是沒有被選中的,如何讓它這一步預設是選中的,或者選中并且是灰色的(比如像Media Player這一項),不讓客戶改變呢?我們需要修改編譯完的vlc的vlc.win32.nsi檔案。然後用它重新制作vlc-0.9.4-win32.exe.     具體修改過程如下:     在vlc.win32.nsi檔案中,找到:

vlc應用

Section /o $Name_Section04 SEC04 

vlc應用

SectionIn 3     修改為:

vlc應用

Section $Name_Section04 SEC04 

vlc應用

SectionIn 1 2 3      或者在1 2 3後面加入“空格RO”,表示這項是必須的不能去掉,就是選中并且是灰色的。$Name_Section04可以替換為"My ActiveX plugin (required)"等自己的名字。

vlc應用

    然後根據前面部落格講的制作vlc-0.9.4-win32.exe的過程執行一遍,然後再制作cab包就okay了。        10. 關于vlc的Activex的說明     根據我對vlc的Activex的使用,發現這個Activex做的真是不好,很多方法沒有封裝進來,如果擴充這個Activex,工作量不小。如果是做C/S程式, 強烈不建議用Activex來開發。除非是想簡單做一下,快速開發等。做C/S播放器還是看我這篇部落格:《 vlc的應用之三:動态調用vlc-0.9.4的libvlc.dll 》,開發過程雖然慢點,但是比較可控。 Activex隻适合應用于B/S項目,隻适合WEB開發,這是Jeremiah的一點忠告,但是隻屬于個人意見,僅供參考。 vlc的應用之三:動态調用vlc-0.9.4的libvlc.dll     vlc-0.9.4提供的libvlc.dll是可以動态調用的,Jeremiah這一篇部落格就介紹下如何用C#和WinForm架構調用libvlc.dll作個簡易播放器。       1. vs2005建立工程,将vlc-0.9.4的libvlc.dll,libvlccore.dll,plugins目錄全部拷貝到工程目錄下面/bin/Debug中。       2. 建立異常結構體

vlc應用

using System; 

vlc應用

using System.Collections.Generic; 

vlc應用

using System.Text; 

vlc應用
vlc應用

namespace MyOwnPlayer 

vlc應用

vlc應用

         //異常結構體 

vlc應用

         public  struct ExceptionStruct 

vlc應用

        { 

vlc應用

                 private  int raised; 

vlc應用

                 private  int code; 

vlc應用

                 private  string message; 

vlc應用

        } 

vlc應用
vlc應用

         class MediaException 

vlc應用

        { 

vlc應用

        } 

vlc應用

}       3. CoreHandle和Core類

vlc應用

using System; 

vlc應用

using System.Runtime.InteropServices; 

vlc應用
vlc應用

namespace MyOwnPlayer 

vlc應用

vlc應用

         class CoreHandle : SafeHandle 

vlc應用

        { 

vlc應用

                 //構造方法 

vlc應用

                 public CoreHandle() 

vlc應用

                        :  base(IntPtr.Zero,  true) 

vlc應用

                { 

vlc應用

                } 

vlc應用
vlc應用

                 //重寫的方法 

vlc應用

                 public  override  bool IsInvalid 

vlc應用

                { 

vlc應用

                        get {  return handle == IntPtr.Zero; } 

vlc應用

                } 

vlc應用
vlc應用

                 protected  override  bool ReleaseHandle() 

vlc應用

                { 

vlc應用

                         if (!IsInvalid) 

vlc應用

                        { 

vlc應用

                                libvlc_release( this); 

vlc應用

                                handle = IntPtr.Zero; 

vlc應用

                        } 

vlc應用

                         return  true; 

vlc應用

                } 

vlc應用
vlc應用

                 protected  override  void Dispose( bool disposing) 

vlc應用

                { 

vlc應用

                        ReleaseHandle(); 

vlc應用

                         base.Dispose(disposing); 

vlc應用

                } 

vlc應用
vlc應用

                 //Dll動态導入 

vlc應用

                [DllImport( "libvlc")] 

vlc應用

                 private  static  extern  void libvlc_release(CoreHandle coreHandle); 

vlc應用

        } 

vlc應用

vlc應用

using System; 

vlc應用

using System.Runtime.InteropServices; 

vlc應用
vlc應用

namespace MyOwnPlayer 

vlc應用

vlc應用

        class Core 

vlc應用

        { 

vlc應用

                //coreHandle字段和屬性 

vlc應用

                private CoreHandle coreHandle; 

vlc應用

                public CoreHandle CoreHandle 

vlc應用

                { 

vlc應用

                        get { return coreHandle; } 

vlc應用

                } 

vlc應用
vlc應用

                //構造方法 

vlc應用

                public Core(string[] argv, ref ExceptionStruct ex) 

vlc應用

                { 

vlc應用

                        coreHandle = libvlc_new(argv.Length, argv, ref ex); 

vlc應用

                } 

vlc應用
vlc應用

                //Dll動态導入 

vlc應用

                [DllImport("libvlc")] 

vlc應用

                private static extern CoreHandle libvlc_new(int argc, string[] args, ref ExceptionStruct ex); 

vlc應用

        } 

vlc應用

      3. MediaHandle和Media類,注意裡面的非英文路徑處理方法。

vlc應用

using System; 

vlc應用

using System.Runtime.InteropServices; 

vlc應用
vlc應用

namespace MyOwnPlayer 

vlc應用

vlc應用

        class MediaHandle : SafeHandle 

vlc應用

        { 

vlc應用

                //構造方法 

vlc應用

                public MediaHandle() 

vlc應用

                        : base(IntPtr.Zero, true) 

vlc應用

                { 

vlc應用

                } 

vlc應用
vlc應用

                //重寫的方法 

vlc應用

                public override bool IsInvalid 

vlc應用

                { 

vlc應用

                        get { return handle == IntPtr.Zero; } 

vlc應用

                } 

vlc應用
vlc應用

                protected override bool ReleaseHandle() 

vlc應用

                { 

vlc應用

                        if (!IsInvalid) 

vlc應用

                        { 

vlc應用

                                libvlc_media_release(this); 

vlc應用

                                handle = IntPtr.Zero; 

vlc應用

                        } 

vlc應用

                        return true; 

vlc應用

                } 

vlc應用
vlc應用

                protected override void Dispose(bool disposing) 

vlc應用

                { 

vlc應用

                        ReleaseHandle(); 

vlc應用

                        base.Dispose(disposing); 

vlc應用

                } 

vlc應用
vlc應用

                //Dll動态導入 

vlc應用

                [DllImport("libvlc")] 

vlc應用

                private static extern void libvlc_media_release(MediaHandle mediaHandle);                 

vlc應用

        } 

vlc應用

vlc應用

using System; 

vlc應用

using System.Text; 

vlc應用

using System.Runtime.InteropServices; 

vlc應用
vlc應用

namespace MyOwnPlayer 

vlc應用

vlc應用

         class Media 

vlc應用

        { 

vlc應用

                 //mediaHandle字段和屬性 

vlc應用

                 private MediaHandle mediaHandle; 

vlc應用

                 public MediaHandle MediaHandle 

vlc應用

                { 

vlc應用

                        get {  return mediaHandle; } 

vlc應用

                } 

vlc應用
vlc應用

                 //構造方法                

vlc應用

                 public Media(CoreHandle coreHandle, String filename,  ref ExceptionStruct ex) 

vlc應用

                { 

vlc應用

                         //c#為UTF-16編碼, libvlc.dll為UTF-8編碼, 需要轉換. 

vlc應用

                        UTF8Encoding utf8 =  new UTF8Encoding(); 

vlc應用

                        mediaHandle = libvlc_media_new(coreHandle, utf8.GetBytes(filename),  ref ex); 

vlc應用

                } 

vlc應用
vlc應用

                 //Dll動态導入 

vlc應用

                [DllImport( "libvlc")] 

vlc應用

                 private  static  extern MediaHandle libvlc_media_new 

vlc應用

                        (CoreHandle coreHandle, [MarshalAs(UnmanagedType.LPArray)]  byte[] link,  refExceptionStruct ex); 

vlc應用

                } 

vlc應用

      5. MediaPlayerHandle和MediaPlayer類

vlc應用

using System; 

vlc應用

using System.Runtime.InteropServices; 

vlc應用
vlc應用

namespace MyOwnPlayer 

vlc應用

vlc應用

         class MediaPlayerHandle : SafeHandle 

vlc應用

        { 

vlc應用

                 //構造方法 

vlc應用

                 public MediaPlayerHandle() 

vlc應用

                        :  base(IntPtr.Zero,  true) 

vlc應用

                { 

vlc應用

                } 

vlc應用
vlc應用

                 //重寫的方法 

vlc應用

                 public  override  bool IsInvalid 

vlc應用

                { 

vlc應用

                        get {  return handle == IntPtr.Zero; } 

vlc應用

                } 

vlc應用
vlc應用

                 protected  override  bool ReleaseHandle() 

vlc應用

                { 

vlc應用

                         if (!IsInvalid) 

vlc應用

                        { 

vlc應用

                                libvlc_media_player_release(this);

vlc應用

                                handle = IntPtr.Zero; 

vlc應用

                        } 

vlc應用

                         return  true; 

vlc應用

                } 

vlc應用
vlc應用

                 protected  override  void Dispose( bool disposing) 

vlc應用

                { 

vlc應用

                        ReleaseHandle(); 

vlc應用

                         base.Dispose(disposing); 

vlc應用

                } 

vlc應用
vlc應用

                 //Dll動态導入 

vlc應用

                [DllImport( "libvlc")] 

vlc應用

                 private  static  extern  void libvlc_media_player_release(MediaPlayerHandle mediaPlayerHandle); 

vlc應用

        } 

vlc應用

vlc應用

using System; 

vlc應用

using System.Runtime.InteropServices; 

vlc應用
vlc應用

namespace MyOwnPlayer 

vlc應用

vlc應用

         class MediaPlayer 

vlc應用

        { 

vlc應用

                 //mediaPlayerHandle字段和屬性 

vlc應用

                 private MediaPlayerHandle mediaPlayerHandle; 

vlc應用

                 public MediaPlayerHandle MediaPlayerHandle 

vlc應用

                { 

vlc應用

                        get {  return mediaPlayerHandle; } 

vlc應用

                } 

vlc應用
vlc應用

                 //構造方法 

vlc應用

                 public MediaPlayer(MediaHandle mediaHandle,  ref ExceptionStruct ex) 

vlc應用

                { 

vlc應用

                        mediaPlayerHandle = libvlc_media_player_new_from_media(mediaHandle,  ref ex); 

vlc應用

                } 

vlc應用
vlc應用

                 //設定父視窗 

vlc應用

                 public  void VedioSetParent(CoreHandle coreHandle, IntPtr hDT,  ref ExceptionStruct ex) 

vlc應用

                { 

vlc應用

                        libvlc_video_set_parent(coreHandle, hDT,  ref ex); 

vlc應用

                } 

vlc應用
vlc應用

                 //播放 

vlc應用

                 public  void Play( ref ExceptionStruct ex) 

vlc應用

                { 

vlc應用

                        libvlc_media_player_play(mediaPlayerHandle,  ref ex); 

vlc應用

                } 

vlc應用
vlc應用

                 //停止 

vlc應用

                 public  void Stop( ref ExceptionStruct ex) 

vlc應用

                { 

vlc應用

                        libvlc_media_player_stop(mediaPlayerHandle,  ref ex); 

vlc應用

                } 

vlc應用
vlc應用

                 //Dll動态導入 

vlc應用

                [DllImport( "libvlc")] 

vlc應用

                 private  static  extern MediaPlayerHandle libvlc_media_player_new_from_media(MediaHandle libvlc_media_handle,  ref ExceptionStruct ex); 

vlc應用
vlc應用

                [DllImport( "libvlc")] 

vlc應用

                 private  static  extern  void libvlc_video_set_parent(CoreHandle coreHandle, IntPtr hDT, ref ExceptionStruct ex); 

vlc應用
vlc應用

                [DllImport( "libvlc")] 

vlc應用

                 private  static  extern  void libvlc_media_player_play(MediaPlayerHandle mediaPlayerHandle,  ref ExceptionStruct ex); 

vlc應用
vlc應用

                [DllImport( "libvlc")] 

vlc應用

                 private  static  extern  void libvlc_media_player_stop(MediaPlayerHandle mediaPlayerHandle,  ref ExceptionStruct ex); 

vlc應用

        } 

vlc應用

      6. 基本工作做好了。下一步建立一個Form,裡面畫一個Panel(播放容器),畫一個Textbox(播放位址),畫一個Button(播放按鈕),Button的點選事件為:

vlc應用

private void button1_Click(object sender, EventArgs e) 

vlc應用

vlc應用

        //要播放的檔案的uri 

vlc應用

        string uri = this.textBox1.Text; 

vlc應用
vlc應用

         //進行播放的控件的句柄 

vlc應用

        IntPtr hdl = this.panel1.Handle; 

vlc應用
vlc應用

         //播放參數 

vlc應用

        string[] argv = new string[] { "-I", "--ignore-config" }; 

vlc應用
vlc應用

         //vlc對象的建立 

vlc應用

        ExceptionStruct ex = new ExceptionStruct(); 

vlc應用

        Core core = new Core(argv, ref ex); 

vlc應用

        Media media = new Media(core.CoreHandle, uri, ref ex); 

vlc應用

        MediaPlayer player = new MediaPlayer(media.MediaHandle, ref ex); 

vlc應用
vlc應用

         //垃圾回收 

vlc應用

        GC.Collect(); 

vlc應用
vlc應用

         //播放 

vlc應用

        player.VedioSetParent(core.CoreHandle, hdl, ref ex); 

vlc應用

        player.Play(ref ex); 

vlc應用
vlc應用

         //繼續回收垃圾等相關操作 

vlc應用

        GC.Collect(); 

vlc應用

        GC.WaitForPendingFinalizers(); 

vlc應用

}       7. 基本的播放功能就是這樣實作的。其他接口請參考源碼下面的/include/vlc/libvlc.h檔案,裡面有比較詳細的對外接口的說明。       8. 以上代碼已經發送到附件中(MyOwnPlayer.rar),參考網址的樓主寫的代碼也在附件中(Marx_libvlc_wrapper(2).zip)。調試附件請注意第1步。 vlc的應用之四:vlc的Mozilla Plugin     Jeremiah最近研究了下讓vlc支援Mozilla的火狐浏覽器,也就是類似于IE的Activex。現在将研究的結果共享一下。       1. 測試的版本為vlc-0.9.4,當然編譯的環境為舊版本的Cygwin(我的叫法,不是官方的叫法),具體的安裝配置編譯vlc-0.9.4,不明白的去看我的前幾篇部落格,裡面詳細的介紹了。       2. 編譯腳本為configure-vlc04.sh(附件提供)。 PATH=/usr/win32/bin:$PATH / 

PKG_CONFIG_LIBDIR=/usr/win32/lib/pkgconfig / 

CPPFLAGS="-I/usr/win32/include -I/usr/win32/include/ebml" / 

LDFLAGS=-L/usr/win32/lib / 

CC="gcc -mno-cygwin" CXX="g++ -mno-cygwin" / 

./configure / 

         --host=i686-pc-mingw32 / 

         --disable-gtk / 

         --enable-nls --enable-sdl --with-sdl-config-path=/usr/win32/bin / 

         --enable-avcodec --enable-avformat --enable-swscale / 

         --enable-faad --enable-flac --enable-theora / 

         --with-wx-config-path=/usr/win32/bin / 

         --with-freetype-config-path=/usr/win32/bin / 

         --with-fribidi-config-path=/usr/win32/bin / 

         --enable-live555 --with-live555-tree=/usr/win32/live.com / 

         --enable-caca --with-caca-config-path=/usr/win32/bin / 

         --with-xml2-config-path=/usr/win32/bin / 

         --with-dvdnav-config-path=/usr/win32/bin / 

         --disable-cddax --disable-vcdx --enable-goom / 

         --enable-twolame --enable-dvdread / 

         --enable-debug    --enable-dca / 

         --enable-mozilla --with-mozilla-sdk-path=/usr/win32/gecko-sdk / 

         --disable-mkv --disable-taglib       3. 編譯中出錯及解決方法見[url]http://jeremiah.blog.51cto.com/539865/115322[/url]       4. 編譯完成後打包(make package-win32-base)。       5. 将打包好的vlc-0.9.4檔案夾下面的libvlc.dll,libvlccore.dll, plugins, mozilla/npvlc.dll拷貝到一個單獨的目錄下,比如E:/WorkBack/vlc-0.9.4/Mozilla Plugin/dlls。        6. 建立系統資料庫檔案mozilla_plugin.reg(見附件),内容為: Windows Registry Editor Version 5.00 

[HKEY_LOCAL_MACHINE/SOFTWARE/MozillaPlugins/@videolan.org/vlc,version=0.9.4] 

"De.ion"="VLC Multimedia Plugin" 

"Path"="E://WorkBack//vlc-0.9.4//Mozilla Plugin//dlls//npvlc.dll" 

"Product"="VLC media player" 

"Vendor"="VideoLAN" 

"Version"="0.9.4" 

[HKEY_LOCAL_MACHINE/SOFTWARE/VideoLAN/VLC] 

"InstallDir"="E://WorkBack//vlc-0.9.4//Mozilla Plugin//dlls" 

"Version"="0.9.4" 

"Language"="2052"       7. 運作這個系統資料庫檔案。       8. 到打包好的vlc-0.9.4下面的activex目錄中,用火狐打開test.html測試,done! vlc的應用之五:動态調用libvlc.dll的補充     最近Jeremiah在增加以前播放器的功能的時候,被一個中文路徑轉碼問題惡心了兩天,最後終于讓我給解決了。在這跟大家分享這個轉碼的解決方法,以及用視訊本次存儲的接口實作。       在看本篇日志之前,請先看我以前寫的《vlc的應用之三:動态調用vlc-0.9.4的libvlc.dll 》。       補充一:libvlc_new(...)接口的中文路徑轉碼處理

vlc應用

using System; 

vlc應用

using System.Runtime.InteropServices; 

vlc應用
vlc應用

namespace MyOwnPlayer 

vlc應用

vlc應用

         class Core 

vlc應用

        { 

vlc應用

                 //coreHandle字段和屬性    

vlc應用

                 private CoreHandle coreHandle; 

vlc應用

                 public CoreHandle CoreHandle 

vlc應用

                { 

vlc應用

                        get {  return coreHandle; } 

vlc應用

                } 

vlc應用
vlc應用

                 //構造方法    

vlc應用

                 public Core( string[] argv,  ref ExceptionStruct ex) 

vlc應用

                { 

vlc應用

                         byte[][] argvbytes =  new  byte[argv.Length][]; 

vlc應用
vlc應用

                         for ( int i = 0; i < argv.Length; i++) 

vlc應用

                        { 

vlc應用

                                argvbytes[i] = Encoding.UTF8.GetBytes(argv[i]); 

vlc應用

                        } 

vlc應用
vlc應用

                        coreHandle = libvlc_new(argv.Length, ReturnIntPtr(argvbytes, argv.Length),  ref ex); 

vlc應用

                } 

vlc應用
vlc應用

                 //轉換函數 

vlc應用

                 private IntPtr ReturnIntPtr( byte[][] data,  int length) 

vlc應用

                { 

vlc應用

                        IntPtr[] dataIntPtrArr =  new IntPtr[length]; 

vlc應用

                         for ( int i = 0; i < length; i++) 

vlc應用

                        { 

vlc應用

                                dataIntPtrArr[i] = Marshal.AllocHGlobal(data[i].Length *  sizeof( byte)); 

vlc應用

                                Marshal.Copy(data[i], 0, dataIntPtrArr[i], data[i].Length); 

vlc應用

                        } 

vlc應用

                        IntPtr dataIntPtr = Marshal.AllocHGlobal(length * Marshal.SizeOf( typeof(IntPtr))); 

vlc應用

                        Marshal.Copy(dataIntPtrArr, 0, dataIntPtr, length); 

vlc應用

                         return dataIntPtr; 

vlc應用

                } 

vlc應用
vlc應用

                 //Dll動态導入    

vlc應用

                [DllImport( "libvlc")] 

vlc應用

                 private  static  extern CoreHandle libvlc_new( int argc, IntPtr argv,  ref ExceptionStruct ex); 

vlc應用

        } 

vlc應用

}       補充二:本地存儲。     對libvlc_new的argv進行轉碼的主要目的就是為了進行本地存儲,由于要将存儲路徑傳入到argv中,是以要對中文的存儲路徑進行轉碼。下面的做法是将視訊流預設存儲為ts流,邊播放邊存儲。

vlc應用

//avPath是本地存儲路徑,需要注意路徑的/和/的問題。 

vlc應用

argv =  new  string[] {  "--sout=#duplicate{dst=display,dst=std{access=file,mux=ts,dst=" + avPath + "}}" }; 

vlc應用
vlc應用

//其他的就跟上一篇部落格一樣了。 

vlc應用

core =  new Core(argv,  ref ex); 

vlc應用

media =  new Media(core.CoreHandle, link,  ref ex); 

vlc應用

player =  new MediaPlayer(media.MediaHandle,  ref ex); 

vlc應用

player.Play( ref ex); //一面播放一面存儲         關于其他形式的argv,可以在vlc的存儲裡面獲得。vlc -> 媒體 -> convert/save -> 轉換/儲存。根據選擇不同的形式,在vlc界面的下半部分會有Generated stream output string。這個就是具體的argv。不過,請注意将:sout換成--sout。   參考網址: 1.  [url]http://rogerfd.cn/?p=189[/url] 寫在這篇部落格之後:

1. Jeremiah對vlc其實并不熟,我也不是vlc專家,視訊伺服器專家,呵呵,是以,有時候大家問我的問題,其實,我自己也很不明白,不能誤導大家。但是我隻要明白的,懂得的,都會毫不保留的跟大家交流。Jeremiah隻是根據自己的業務需求來用vlc,當然,用vlc第一步就是要編譯它。編譯vlc花了我N多心血。其他的業務需求主要是借用vlc作一個自己的軟解碼器,播放網絡H264流。是以,對vlc用戶端的學習多一些,包括C#調用vlc接口,還有activex控件的相關内容。但是對vlc的伺服器方面的應用掌握的不夠多。Jeremiah略懂java,略懂C#,但是對C,C++,VC及控件等,非常不熟悉,是以,研習vlc代碼,一直遲遲沒有進行。   2. Jeremiah編譯這幾個版本的vlc,都是經過嚴格的測試,才發到部落格上面的,而且,盡量的寫的已經不能再詳細的地步。是以,如果根據我的部落格編譯不成功,肯定是哪一步沒有搞正确。如果每一步都搞正确了,最後還沒有編譯成功,我隻能說RP到極點了。   3. 很多時候Google比Jeremiah好用許多。很多資訊都會出現在官網的文檔上。還有./configure -h和vlc -H這些指令也能提供很多資料,研習下這些資料,比Jeremiah直接告知,能學到更多的東西。   4. vlc研究群裡面有N多高手,如果有問題得不到解決,去群裡面忽悠忽悠吧。   5. vlc這個專題的文章,Jeremiah以後會繼續發,但是由于本人能力有限,估計不會經常更新了。不過隻要我學到了新的關于vlc的東西,我就會整理了發上來。也希望各位高手能能多多幫助我,多多提意見。   6. vlc的調用過程大體說一下,一般都是vlc界面或者activex或者自己寫的程式->libvlc.dll->libcore.dll->plugins,是以,在進行相關調試的時候,這樣的目錄結構是不能變的,也就是libvlc.dll,libcore.dll,plugins目錄是在一級目錄下面,而不是一堆dll在一個目錄下面。   7. 2009-03-11開通vlc中文論壇,位址為:http://bbs.dvbcn.com/vlc/。   寫得比較亂,先到此,以後想起什麼,再補充。 vlc的應用之六:簡單的視訊點播系統(B/S)的實作         前兩天幫“豬小妹”考慮畢業設計的時候,想了想視訊點播系統的該如何實作。在這寫一下自己的想法和非常簡單的實作方式,純屬娛樂,請勿拍磚。           1. 大體的架構及流程         實作視訊點播系統,B/S架構,服務端至少應該是兩個伺服器:流媒體伺服器,web伺服器。用戶端則就是web頁面。當開啟頁面後則是用戶端和伺服器的第一次互動,通過http協定得到頁面。裡面會有流媒體位址的資訊,浏覽器裡面點選顯示視訊元件,将流媒體的位址傳給流媒體播放器,并啟動播放器去請求視訊。這是第二次互動。伺服器端流媒體伺服器發送流給用戶端,頁面上播放就okay了。           2. 環境及所需軟體         Jeremiah的測試環境是xp sp2及IE8浏覽器。IP位址:172.16.128.8. 與IP有關的位址,請根據個人情況自己改。         服務端:         流媒體伺服器先用個簡單的:live555 Media Server(http://www.live555.com/mediaServer/windows/live555MediaServer.exe)         Web伺服器:Jeremiah以前學的JAVA,是以用Tomcat。IIS或者其他的Web伺服器都可以。其實Jeremiah這個小系統用的是靜态頁面,是以如果是在本機測試的話,不用Web伺服器也是okay的。模拟本地打開為Web浏覽。         用戶端:vlc-0.9.4的Activex。需要把Activex注冊好(參考http://jeremiah.blog.51cto.com/539865/115943)           3. 配置流媒體伺服器         下載下傳完live555 Media Server之後放到d:/video下面,啟動時會有以下資訊: "Play streams from this server using the URL

        rtsp://172.16.128.8/<filename>

where <filename> is a file present in the current directory." 并且後面還會有live555支援的視訊格式。 本測試就用的mp3和ts格式。其他格式沒有試驗過。         mp3好說,ts怎麼得到呢?這時候vlc就出場了。vlc有轉換儲存功能,媒體->轉換/儲存->選擇某個檔案後點選轉換/儲存->流輸出頁面勾選本地播放,勾選檔案并且浏覽得到個檔案名,注意字尾為ts而不是ps,方案封裝選MPEG-TS,然後點選save。把你選擇的視訊播放一遍之後,ts格式的檔案就生成好了。         将生成好的ts檔案和網上下載下傳的mp3放到d:/video下面,本測試為01.ts及02.mp3。這樣流媒體伺服器就配置好了。           4. web頁面代碼         本web頁面代碼是vlc的Activex測試代碼test.html上修改精簡的。(沒寫注釋,因為看着不難。) vod.html: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" > 

< html  xmlns ="http://www.w3.org/1999/xhtml"  > 

< head > 

< meta  http-equiv ="Content-Type"  content ="text/html; charset=UTF-8"  /> 

< script > 

var itemId = 0; 

function getVLC(name) 

        if (window.document[name])    

        { 

                return window.document[name]; 

        } 

        if (navigator.appName.indexOf("Microsoft Internet")==-1) 

        { 

                if (document.embeds && document.embeds[name]) 

                        return document.embeds[name];    

        } 

        else 

        { 

                return document.getElementById(name); 

        } 

function doGo(mrl) 

        var vlc = getVLC("vlc"); 

        itemId=vlc.playlist.add(mrl); 

        vlc.playlist.playItem(itemId); 

        document.getElementById("btn_stop").disabled = false; 

function updateVolume(deltaVol) 

        var vlc = getVLC("vlc"); 

        vlc.audio.volume += deltaVol; 

function doPlay() 

        vlc.playlist.playItem(itemId); 

        document.getElementById("btn_stop").disabled = false; 

        document.getElementById("btn_play").disabled = true; 

function doStop() 

        getVLC("vlc").playlist.stop(); 

        document.getElementById("btn_stop").disabled = true; 

        document.getElementById("btn_play").disabled = false; 

</script> 

</head> 

< body > 

< div  style ="margin: 50px" > 

         < a  title ="rtsp://172.16.128.8/01.ts"  href ="#"  onclick ="doGo(this.title);return false;" >01.ts </a> 

         < span  style ="margin: 20px;"  /> 

         < a  title ="rtsp://172.16.128.8/02.mp3"  href ="#"  onclick ="doGo(this.title);return false;" >02.mp3 </a> 

         < span  style ="margin: 20px;"  /> 

</div> 

< div > 

        <object classid="clsid:9be31822-fdad-461b-ad51-be1d1c159921" 

                width="640" 

                height="480" 

                id="vlc" 

                events="true"> 

         < param  name ="mrl" value=""  /> 

         < param  name ="showdisplay"  value ="true"  /> 

         < param  name ="autoloop"  value ="false"  /> 

         < param  name ="autoplay"  value ="false"  /> 

         < param  name ="volume"  value ="50"  /> 

         < param  name ="starttime"  value ="0"  /> 

        <embed pluginspage="http://www.videolan.org" 

                     type="application/x-vlc-plugin" 

                     version="videolan.vlcplugin.2" 

                     width="640" 

                     height="480" 

                     name="vlc"> 

         </embed> 

         </object> 

</div> 

< div > 

< input type=button  id ="btn_play"  value =" 播放 "  onClick ='doPlay();'  disabled ="true" > 

< input type=button  id ="btn_stop"  value ="停止"  onClick ='doStop();'  disabled ="true" > 

< input type=button  value ="靜音切換"  onclick ='getVLC("vlc").audio.togglemute();' > 

< input type=button  value ="減小音量"  onclick ='updateVolume(-10)' > 

< input type=button  value ="增加音量"  onclick ='updateVolume(+10)' > 

</div> 

</body> 

</html> 将vod.html放置到Web伺服器中。我就不多說了。so簡單。           5. 通路vod.html         通路前請確定用戶端Activex控件已注冊成功。         打開IE輸入http://172.16.128.8:8080/vod/vod.html後通路到我們上面寫的頁面。然後點選01.ts超連結,在下面的vlc的Activex上就會顯示視訊了。這樣,一個簡單的點播系統就做好了。 請注意下面圖檔的視訊上的位址。

vlc應用

          6. C/S架構的實作         做成跟pplive類似的用戶端,考慮與伺服器的兩次交流,第二次交流是沒有問題的,關鍵在第一次交流上。如果用戶端做成嵌入IE的方式,如C#的WebBrowser,則點選某個視訊位址的資訊子產品,如超連結,無法将超連結的位址傳給播放器元件了。Jeremiah考慮的解決的方法就是第一次與Web伺服器的交流可以用xml來實作。用戶端擷取xml,然後解析,然後顯示到某個元件裡面,如C#的Listbox,這樣點選這個元件就可以輕易的将視訊位址傳給播放器元件了。pplive的頻道清單,估計就是用的這種方式。 vlc的應用之七:用vlc做單點傳播,多點傳播及點播伺服器     還是前兩天幫“豬小妹”考慮畢業設計的時候,想了想vlc能不能作為vod的伺服器,替代上一篇部落格裡面的live555 media server,因為live555 media server做的确實不是太好。查了些資料,在vlc群裡面亂問了一通,終于解決了。好東西啊,大家共享。

    在這感謝vlc研究群“櫻木”童鞋提供的幫助。       1. 所需軟體

    vlc-0.9.9或vlc-0.8.6i,主要測試的是比較新的0.9.9版本的。

    putty:一款集telnet,ssh遠端登陸的非常好的軟體。下載下傳位址:http://wrc.gro.clinux.org/putty/putty.exe       2. 指令行啟動vlc,并打開背景資訊顯示,有助于觀察背景資訊

    開啟cmd,并cd到vlc的目錄,執行 vlc -vv --extraintf=logger       3. 開啟vlc的telnet服務

    vlc-0.9.9在界面上選擇工具->界面->telnet控制台

    背景dos視窗會有反應,顯示 [00000403] main interface debug: looking for interface module: 1 candidate 

[00000403] main interface debug: creating VLM 

[00000405] main vlm daemon debug: thread 5112 (vlm thread) created at priority 0 

(../../src/input/vlm.c:112) 

[00000405] main vlm daemon debug: thread started 

[00000403] telnet interface: using the VLM interface plugin... 

[00000403] main interface debug: net: listening to 127.0.0.1 port 4212 

[00000403] telnet interface: telnet interface started on interface 127.0.0.1 421 

[00000403] main interface debug: using interface module "telnet" 

[00000403] main interface debug: TIMER module_Need() : 19.000 ms - Total 19.000 

ms / 1 intvls (Avg 19.000 ms) 

[00000403] main interface debug: thread 5136 (interface) created at priority 0 ( 

../../src/interface/interface.c:168) 

[00000403] main interface debug: thread started     注意觀察main interface debug: net: listening to 127.0.0.1 port 4212這句話,說明vlc現在的telnet監聽的是127.0.0.1這個位址和4212這個端口。如果沒有顯示ip的話,一般用127.0.0.1是沒有問題的。127.0.0.1就表示的本機,與localhost是同一個意義。       4. 啟動putty.exe

    主機名稱(或ip)輸入:127.0.0.1

    端口:4212

    連接配接類型:選Telnet

    點打開。

    如果沒有出現"Password:"字樣,點打開就關閉了,那就說明沒有telnet上。(這個時候可以在cmd裡面輸入telnet 127.0.0.1 4212,看結果應該是正在連接配接到127.0.0.1...不能打開到主機的連接配接, 在端口 4212: 連接配接失敗,或者是與主機失去連接配接。不用cmd的telnet連接配接的主要原因是過會輸入指令的時候看不到。)這個時候,請關閉防火牆,防毒軟體及一切相關軟體,不過中毒了别找我哎。(*^__^*) 嘻嘻……繼續繼續。

    如果沒有出現以上問題,在Password:後面輸入"admin",沒有明文回顯。登入成功後會顯示:Welcome, Master。       5. 架設點播服務vod

    分别輸入: new vod1 vod enabled 

setup vod1 input d:/01.avi     解釋下:

    new了一個名字叫vod1的vod,設定vod1的input為d:/01.avi。     驗證:開啟另一個vlc,打開rtsp://127.0.0.1/vod1。應該就可以播放了。127.0.0.1可以換成自己的ip。       6. 架設多點傳播伺服器

    繼續輸入: new ch1 broadcast enabled 

setup ch1 input d:/02.avi [loop] 

setup ch1 output #duplicate{dst=rtp{dst=226.0.0.6,mux=ts,port=1234}} 

control ch1 play     解釋下:

    new了一個名字叫ch1的broadcast。設定ch1的input為d:/02.avi,loop可選,表示循環播放。設定ch1的output為#duplicate{dst=rtp{dst=226.0.0.6,mux=ts,port=1234}},表示rtp協定的ts流發送到多點傳播位址為226.0.0.6,端口1234。控制ch1播放。

     擴充:

    1) output後面可以跟sout參數。具體可以參考vlc->媒體->流->流輸出界面的已生成的流輸出字元串。

    2) control ch1後面還可以加stop,pause,seek 百分比。表示停止,暫停和跳轉到百分之幾的位置。     驗證:開啟一個vlc,打開rtp://226.0.0.6:1234。應該就可以播放了。       7. 架設單點傳播伺服器

    第6步裡面的output換成單點傳播的位址就行了。其他的都一樣的。注意不要new重名了。       8. 儲存剛才操作

    繼續輸入 save d:/01.cfg     将剛才操作儲存到了d:/01.cfg裡面,除了control。可以通過記事本等文本編輯器檢視一下裡面的内容。

    如果重新開啟了vlc,則可以輸入 load d:/01.cfg     将剛才儲存的操作讀入進來,繼續操作或控制。               通過這樣的配置,一個vlc的執行個體可以提供多個服務,包括單點傳播,多點傳播和點播。确實強大啊。     這樣上一篇部落格的流媒體伺服器可以替換為vlc了。跟上一篇日志結合作個簡單的流媒體服務的網站或者類似于pplive的用戶端,就不是太有技術難度的事情了。 vlc的應用之八:MFC調用libvlc.dll     本篇部落格将簡單介紹MFC調用libvlc.dll作一個簡單的播放器,抛磚引玉,各位VC++達人繼續深入研究,Jeremiah對VC++确實不太感興趣,是以就不做太深入的研究了。   2009.10.29修改:加入clip_children屬性設定。參考第1步。 2010.04.14修改:中文路徑問題。參考第7步。       環境:

        1) VC6 SP5

        2) vlc-0.9.9a

    0. 引言

    根據上一篇部落格的研究,任何一個VC環境都可以調用MinGW/Gcc編譯得到的libvlc.dll。VLC在編譯打包之後(也就是執行完make package-win32-base),或者去官網下載下傳zip包解壓之後,或者是安裝完VLC之後,在vlc-0.9.9a目錄下有個sdk檔案夾,裡面又包含兩個檔案夾:include--頭檔案及lib--庫。這些都是我們用MFC調用libvlc.dll所必須的。頭檔案沒啥好說的,庫裡面的libvlc.dll.a及libvlccore.dll.a就是上一篇部落格所說的靜态庫,我們分别手動改成libvlc.lib及libvlccore.lib就可以在VC環境中調用啦。下面簡要說一下調用的過程,對各位VC++達人來說絕對是小菜一碟。       1. 建立工程

    建立MFC AppWizard(exe)工程,名字為:MFCVLC。選擇項目為Dialog based,點選完成。删除Dialog窗體上的所有的控件,包括“确定”、“取消”按鈕及"TODO"靜态文本。勾選視窗的clip_children屬性,這樣就會避免拖動、最大化最小化及全屏還原時找不到圖像的缺陷。

vlc應用

        2. 畫控件

    畫四個控件,兩個靜态文本框,一個輸入框,一個按鈕。其中,第一個靜态文本框修改Caption為“路徑:”,第二個文本框為視訊的顯示區域,是以講ID改為IDC_DISPLAY,Caption去掉。輸入框關聯一個變量,CString類型,命名為m_path。按鈕的Caption改為“播放”,并為BN_CLICKED增加一個Function。在CMFCVLCdlg的構造方法中加入一下語句友善調試。

vlc應用

m_path = _T( "d:/01.avi");  // 輸入常用的視訊位址  

vlc應用

        3. 拷貝vlc的相關庫及頭檔案

    在資料總管的MFCVLC工程目錄下建立檔案夾vlc,lib,将vlc-0.9.9a/sdk/include/vlc.h拷貝到MFCVLC工程目錄下,将vlc-0.9.9a/sdk/include除了vlc.h之外的所有檔案拷貝到vlc目錄下,将vlc-0.9.9a/sdk/lib下的libvlc.dll.a及libvlccore.dll.a拷貝到lib下,并分别修改為libvlc.lib及libvlccore.lib。将vlc-0.9.9a目錄下的libvlc.dll, libvlccore.dll, plugins目錄拷貝到Debug目錄下。如果有Cygwin環境,需要将stdint.h(/usr/include/stdint.h)這個頭檔案也拷貝到MFCVLC工程目錄下。在VC6環境中FileView中建立檔案夾及導入上述檔案,最後入下圖所示。

vlc應用

      4. 修改頭檔案

    1) 修改vlc.h,将所有的#include <***>改為 #include "***"     2) 修改stdint.h,将所有的long long替換為__int64     3) 修改libvlc_structures.h,#include <stdint.h>為#include "stdint.h"         5. 編寫代碼

    在MFCVLCDlg.cpp中加入頭檔案導入。

vlc應用

#include  "vlc.h"       在button的onclick關聯函數中加入代碼:

vlc應用

void CMFCVLCDlg::OnButton1()    

vlc應用

vlc應用

   // TODO: Add your control notification handler code here 

vlc應用

     char path[100]; 

vlc應用

     this->GetDlgItemText(IDC_EDIT1, path, 100); 

vlc應用

    libvlc_exception_t ex; 

vlc應用

    libvlc_exception_init(&ex); 

vlc應用

     int vlc_argc = 0; 

vlc應用

     char *vlc_argv[100]; 

vlc應用

    vlc_argv[vlc_argc++] =  "--ignore-config"; 

vlc應用

    libvlc_instance_t *p_instance = libvlc_new( 

vlc應用

          vlc_argc, vlc_argv, &ex); 

vlc應用

    libvlc_media_t *p_media = libvlc_media_new( 

vlc應用

          p_instance, path, &ex); 

vlc應用

    libvlc_media_player_t *p_media_player    

vlc應用

        = libvlc_media_player_new_from_media( 

vlc應用

            p_media, &ex); 

vlc應用

    libvlc_drawable_t hwnd =    

vlc應用

        (libvlc_drawable_t)  this->GetDlgItem(IDC_DISPLAY)->GetSafeHwnd(); 

vlc應用

    libvlc_media_player_set_drawable(p_media_player, hwnd, &ex); 

vlc應用

    libvlc_media_player_play(p_media_player, &ex); 

vlc應用

}

    6. 關聯靜态庫及編譯運作

    打開Project Setting,在link标簽的Object/library modules:下輸入 lib/libvlc.lib lib/libvlccore.lib。

    build項目,應該沒有錯誤。

    Execute Program就可以執行了。       7. 兩個BUG

    第6步執行的是Execute模式,如果是Debug模式,點選“播放”後,背景會顯示加載的vlc的plugins的dll的資訊,但是加載完最後一個dll的時候程式就Block住了。暫時不曉得為啥。經過更多的測試(win2003虛拟機裡的vc6),發現Jeremiah的VC6可能真的有問題,debug的時候,打開Output視窗顯示加載的dll的情況,就會block住。不打開Output視窗偶爾會set_drawable不成功,彈出新視窗。其他幾位朋友測試則正常。     上面的代碼如果開帶中文路徑的位址會無法打開,因為傳入的中文路徑vlc識别不了。需要将路徑也就是path變量從ANSIZ轉換為UTF8代碼。具體怎麼轉換,各位VC達人自己研究吧。       8. 用VC6以上版本調試結果     Jeremiah使用了vs2003及vs2005。     1)  會兩個重複定義的錯誤,解決方法是将stdint.h中注釋掉:

vlc應用

#ifndef __intptr_t_defined 

vlc應用

#define __intptr_t_defined 

vlc應用

//typedef long intptr_t; 

vlc應用

#endif 

vlc應用

//typedef unsigned long uintptr_t;     2) 釋出Release版本會報記憶體錯誤。具體原因待查,應該是.lib不相容的問題。不知道為啥Debug版就可以而Release版就不行。解決方法是用dll2lib.exe(附件提供)将0.9.9a的libvlc.dll及libvlccore.dll轉換為相應的lib庫,替換工程的lib/下面的相應的庫,然後再次Release即可。

    Jeremiah對MFC隻有一點點了解,是以上述的各個過程如果重複煩瑣,及如何修複第7,8步講的BUG及問題,請各位VC++達人指導Jeremiah。先謝過。本文附件中提供了MFCVLC的源碼,隻是需要把vlc-0.9.9a的libvlc.dll, libvlccore.dll, plugins目錄拷貝到Debug目錄下就可以編譯執行。需要的自己下載下傳添加調試。

vlc的應用之九:用vlc串流攝像頭     n就沒有更新部落格了,主要是Jeremiah最近對vlc研究的非常的少了,工作重點轉移了,又增加了管理工作,讓Jeremiah忙的暈頭轉向的。       這篇部落格是很久之前就想寫的,今天終于提筆寫了,心情還是比較爽的。廢話不多說。   0. 環境搭建

Jeremiah這次主要是用的vlc-1.0.0(英文版)進行講解。首先需要準備攝像頭,Jeremiah用的是一個普通攝像頭(以前釣MM用的,嘻嘻),驅動安裝好後,在“我的電腦”中顯示如下。

vlc應用

  1. vlc播放攝像頭 開啟vlc-1.0.0,media->open capture device,進入Capture Device頁面。這個也可以通過media->Advanced open file,選取此标簽頁。

video device name選擇VIMICRO USB PC Camera (ZC0301PLH),如果沒有,請先選擇Refresh list重新整理清單。

audio device name選擇SoundMAX HD Audio,這個是Jeremiah的聲霸卡。

之後可以勾選show more options,裡面可是設定緩沖及看到MRL和Edit Options,這些資訊都是很重要的。Advance Option按鈕裡面有一些詳細設定,大家可以進去選擇,其中video size是可以做調整的。下面會講到。

之後點play,就可以播放了。   2. 用指令行開啟vlc播放攝像頭

指令行的最大好處就是,vlc指令後面的參數,就是我們在程式設計的時候調用libvlc_new的argv,将這些參數搞明白,我們就可以在程式設計的時候調用了。

開啟cmd,切換到vlc目錄下。

根據1中的MRL和Edit Options資訊,設定vlc播放參數如下。 vlc dshow:// :dshow-vdev="VIMICRO USB PC Camera (ZC0301PLH)" :dshow-adev="SoundMAX HD Audio" :dshow-size=320*240   各個參數什麼意思都是很明顯的,如果不明白,就運作vlc -H,然後到vlc目錄下面去找vlc-help.txt,裡面是全部的參數的介紹。   3. 将vlc播放的攝像頭資訊存入檔案中 播放成功之後,在達到我們的目的前,我們先做一個簡單的驗證工作,就是播放攝像頭并存入檔案。

根據以前stream到檔案的參數,修改2的參數如下。 vlc dshow:// :dshow-vdev="VIMICRO USB PC Camera (ZC0301PLH)" :dshow-adev="SoundMAX HD udio" :dshow-size=320*240 :sout=#transcode{vcodec=h264,vb=800,scale=1,acodec=mp3,ab=128,channels=2,samplerate=44100}:std{access=file,mux=ts,dst=D:/01.ts}}   這裡用到了轉碼,就是将攝像頭的視訊編碼為h264,音頻編碼為MP3,然後封裝為ts寫入到d:/01.ts中。

這個不會顯示攝像頭,但是通過重新整理d:/01.ts就會發現這個檔案是在增大的,也就是有視訊流在寫入。   4. 将攝像頭串流到網絡中

根據3的參數做簡單的修改就可以達到串流攝像頭視訊流到網絡的目的了。修改3的參數如下。 vlc dshow:// :dshow-vdev="VIMICRO USB PC Camera (ZC0301PLH)" :dshow-adev="SoundMAX HD Audio" :dshow-size=320*240 :sout=#transcode{vcodec=h264,vb=800,scale=1,acodec=mp3,ab=128,channels=2,samplerate=44100}:duplicate{dst=display,dst=rtp{dst=127.0.0.1,mux=ts,port=1234}}   這裡的duplicate大家應該都很熟悉了,因為在錄像,vlm裡面都講過這個參數。參數的意思是,将攝像頭的音視訊流分别編碼為MP3和h264之後封裝為ts,然後通過rtp發送到127.0.0.1的1234端口上,同時顯示出來。如果希望發送到其他網絡位址或多點傳播裡面隻需要改變127.0.0.1和1234為我們需要的位址和端口即可。

再開啟一個vlc,播放這個ts over rtp流。 vlc rtp://@:1234 --rtp-caching=1500   成功後就可以看到了。切圖如下:

vlc應用

  左邊的是攝像頭的流服務,右邊的是流的用戶端,從下邊的位址就能看的很清楚。   5. 遺留問題:

從圖檔可以看出,播放的視訊顔色是不對的,是攝像頭的問題還是vlc本身的問題還是參數設定的問題,現在不得而知,當然攝像頭本身是沒問題的,因為qq視訊都很正常。希望誰研究出來告訴我一聲。謝謝。 vlc的應用之十:vlc的遠端控制

    VLC作為伺服器,可以進行遠端控制。再以前的部落格中提到用telnet配置VLM(《vlc的應用之七:用vlc做單點傳播,多點傳播及點播伺服器》),這也算是一種遠端控制。這次介紹的遠端控制主要包括以下兩種,使用的是vlc-1.0.5。

1. http遠端控制

2. vlc remote control (rc)

    1. vlc的http遠端控制

    指令行執行以下指令。

  1. vlc -I http --http-host=localhost:8866 

    解釋下:-I http就是啟用http服務。--host-host=ip:port為啟用的服務的ip位址及端口号。

    浏覽器下輸入http://localhost:8866,會顯示如下界面。

vlc應用

    點選左上角的open按鈕,打開input框。輸入路徑,點選play。出現視訊畫面。

vlc應用

    http子產品在安裝目錄下面的http目錄下面,通過解析index.html等,可以編寫自己的web頁面,并實作遠端控制vlc的目的。在頁面下方還有VLM的http配置,有興趣的可以去好好研究下。

    注:如果要監聽本機真實ip位址,讓其他機器都能通路,則需要修改http目錄下面的.host檔案,配置相關private addresses。具體請根據自己ip位址進行配置。比如Jeremiah的ip位址為172.16.5.XXX,則隻需要增加172.16.5.XXX/24,其他172.16.5段IP都可以通路了。

    2. vlc remote control

    指令行執行以下指令。

  1. vlc -I rc 

    出現vlc的rc背景。在裡面輸入help,列印出所有可以執行的指令。這些指令即為控制vlc的指令。如下圖所示。

vlc應用

    輸入add d:/video/01.avi,則開始播放視訊。如下圖所示。

vlc應用

    當然,我們也寫程式遠端控制vlc。主要思路就是建立一個socket,連接配接到vlc的rc服務,然後發送控制指令就可以了。

    1) 指令行運作以下指令。

  1. vlc -I rc --rc-host=localhost:8888 

    解釋下:-I rc就是啟動rc服務,--rc-host=ip:host就是監聽的ip及端口号,一般ip設定為localhost。

    2) 編寫程式client_vlc.c如下。

  1. /******************************************************************************  
  2. * Filename:        client_vlc.c   
  3. * Created on:      Apr 4, 2010    
  4. * Author:          jeremiah    
  5. * Description:     vlc的用戶端程式,測試vlc遠端控制  
  6. *    
  7. ******************************************************************************/ 
  8. #include <stdio.h>  
  9. #include <stdlib.h>  
  10. #include <string.h>  
  11. #include <unistd.h>  
  12. #include <sys/socket.h>  
  13. #include <netinet/in.h>  
  14. #define MAXLINE 4096  
  15. #define SERV_ADDR "127.0.0.1"  
  16. #define SERV_PORT 8888  
  17. int main(int argc, char *argv[]) {  
  18.     struct sockaddr_in servaddr;  
  19.     char buf[MAXLINE];  
  20.     int sockfd;  
  21.     int read_size;  
  22.     // 建立socket  
  23.     sockfd = socket(AF_INET, SOCK_STREAM, 0);  
  24.     bzero(&servaddr, sizeof(servaddr));  
  25.     servaddr.sin_family = AF_INET;  
  26.     inet_pton(AF_INET, SERV_ADDR, &servaddr.sin_addr);  
  27.     servaddr.sin_port = htons(SERV_PORT);  
  28.     // 建立連接配接  
  29.     connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));  
  30.     // 向vlc發請求 "add d:/video/01.avi"  
  31.     write(sockfd, "add d:/video/01.avi/r/n",   
  32.             strlen("add d:/video/01.avi/r/n") + 1);  
  33.     // 列印vlc傳回結果  
  34.     read_size = read(sockfd, buf, MAXLINE);  
  35.     printf("Response from vlc:/n");  
  36.     printf("%s/n", buf);  
  37.     // 向vlc發請求 "is_playing"  
  38.     write(sockfd, "is_playing/r/n", strlen("is_playing/r/n"));  
  39.     // 列印vlc傳回結果  
  40.     read_size = read(sockfd, buf, MAXLINE);  
  41.     printf("Response from vlc:/n");  
  42.     printf("%s/n", buf);  
  43.     // 關閉socket  
  44.     close(sockfd);  
  45.     return 0;  
  46. }  

    3) 編譯上面的程式,本文主要在Cygwin裡面編譯使用。

  1. gcc -o client_vlc client_vlc.c 

    4)執行程式,檢視結果。

vlc應用

    可以看到從伺服器傳回的字元串,顯示添加成功,檢查播放情況顯示no error。關于其他的操作,還是參考上面的help的顯示資訊。

vlc的應用之十一:修改vlc的界面文字    跟一個網友交流的時候,發現有這個需求,看着vlc的中文寫的不爽,想要自己改改vlc界面的中文文字。經過幾天的研究,找到了解決辦法,記錄在此。       其實讀取vlc的Makefile,在package-win32-common目标裡面發現這幾行代碼: # Copy the locales 

                mkdir -p $(win32_destdir)/locale 

                cat $(top_srcdir)/po/LINGUAS | while read i; do / 

                    mkdir -p "$(win32_destdir)/locale/$${i}/LC_MESSAGES" ; / 

                    cp "$(srcdir)/po/$${i}.gmo" / 

                        "$(win32_destdir)/locale/$${i}/LC_MESSAGES/vlc.mo" / 

                        || true ; / 

                done 

    可以看到其實locale檔案夾下面的vlc.mo,是源碼目錄下面的po/zh_CN.gmo檔案。       讀取源碼下面對應的zh_CN.po檔案發現,其實英文界面的每個相關的文字對應的中文,都是在這個po檔案标示出來了。是以,如果要修改vlc的中文界面,修改這個zh_CN.po就可以了。但是要生成對應的gmo檔案,卻沒有找到相關的指令。最後google了n天,找到了以下指令,在Cygwin下運作: /usr/bin/msgfmt -c --statistics -o zh_CN.gmo zh_CN.po       将生成好的zh_CN.gmo檔案複制到vlc二進制目錄的locale/zh_CN/LC_MESSAGES目錄下,替換vlc.mo檔案。然後重新啟動vlc。       Jeremiah修改了zh_CN.po檔案的串流和vlc标題,具體的修改,去查找po檔案的關鍵詞,替換掉就okay了。效果圖如下:

vlc應用

繼續閱讀