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控件,可以在窗體裡面随便畫了。
調用函數如下:
private void button1_Click( object sender, EventArgs e)
{
//輸入參數
string parameter = ":sout=#duplicate{dst=display} :no-overlay";
//判斷是否正在播放
if ( this.axVLCPlugin21.playlist.isPlaying)
{
//如果正在播放, 則停止
this.axVLCPlugin21.playlist.stop();
}
//清空播放清單
this.axVLCPlugin21.playlist.clear();
//添加播放清單
this.axVLCPlugin21.playlist.add(textBox1.Text, null, parameter);
//播放清單更新到新添加的播放項
this.axVLCPlugin21.playlist.next();
//播放
this.axVLCPlugin21.playlist.play();
} 其他函數調用參考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的安裝檔案,然後啟動安裝。但是安裝過程中,出現這樣一步:
Activex plugin預設是沒有被選中的,如何讓它這一步預設是選中的,或者選中并且是灰色的(比如像Media Player這一項),不讓客戶改變呢?我們需要修改編譯完的vlc的vlc.win32.nsi檔案。然後用它重新制作vlc-0.9.4-win32.exe. 具體修改過程如下: 在vlc.win32.nsi檔案中,找到:
Section /o $Name_Section04 SEC04
SectionIn 3 修改為:
Section $Name_Section04 SEC04
SectionIn 1 2 3 或者在1 2 3後面加入“空格RO”,表示這項是必須的不能去掉,就是選中并且是灰色的。$Name_Section04可以替換為"My ActiveX plugin (required)"等自己的名字。
然後根據前面部落格講的制作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. 建立異常結構體
using System;
using System.Collections.Generic;
using System.Text;
namespace MyOwnPlayer
{
//異常結構體
public struct ExceptionStruct
{
private int raised;
private int code;
private string message;
}
class MediaException
{
}
} 3. CoreHandle和Core類
using System;
using System.Runtime.InteropServices;
namespace MyOwnPlayer
{
class CoreHandle : SafeHandle
{
//構造方法
public CoreHandle()
: base(IntPtr.Zero, true)
{
}
//重寫的方法
public override bool IsInvalid
{
get { return handle == IntPtr.Zero; }
}
protected override bool ReleaseHandle()
{
if (!IsInvalid)
{
libvlc_release( this);
handle = IntPtr.Zero;
}
return true;
}
protected override void Dispose( bool disposing)
{
ReleaseHandle();
base.Dispose(disposing);
}
//Dll動态導入
[DllImport( "libvlc")]
private static extern void libvlc_release(CoreHandle coreHandle);
}
}
using System;
using System.Runtime.InteropServices;
namespace MyOwnPlayer
{
class Core
{
//coreHandle字段和屬性
private CoreHandle coreHandle;
public CoreHandle CoreHandle
{
get { return coreHandle; }
}
//構造方法
public Core(string[] argv, ref ExceptionStruct ex)
{
coreHandle = libvlc_new(argv.Length, argv, ref ex);
}
//Dll動态導入
[DllImport("libvlc")]
private static extern CoreHandle libvlc_new(int argc, string[] args, ref ExceptionStruct ex);
}
}
3. MediaHandle和Media類,注意裡面的非英文路徑處理方法。
using System;
using System.Runtime.InteropServices;
namespace MyOwnPlayer
{
class MediaHandle : SafeHandle
{
//構造方法
public MediaHandle()
: base(IntPtr.Zero, true)
{
}
//重寫的方法
public override bool IsInvalid
{
get { return handle == IntPtr.Zero; }
}
protected override bool ReleaseHandle()
{
if (!IsInvalid)
{
libvlc_media_release(this);
handle = IntPtr.Zero;
}
return true;
}
protected override void Dispose(bool disposing)
{
ReleaseHandle();
base.Dispose(disposing);
}
//Dll動态導入
[DllImport("libvlc")]
private static extern void libvlc_media_release(MediaHandle mediaHandle);
}
}
using System;
using System.Text;
using System.Runtime.InteropServices;
namespace MyOwnPlayer
{
class Media
{
//mediaHandle字段和屬性
private MediaHandle mediaHandle;
public MediaHandle MediaHandle
{
get { return mediaHandle; }
}
//構造方法
public Media(CoreHandle coreHandle, String filename, ref ExceptionStruct ex)
{
//c#為UTF-16編碼, libvlc.dll為UTF-8編碼, 需要轉換.
UTF8Encoding utf8 = new UTF8Encoding();
mediaHandle = libvlc_media_new(coreHandle, utf8.GetBytes(filename), ref ex);
}
//Dll動态導入
[DllImport( "libvlc")]
private static extern MediaHandle libvlc_media_new
(CoreHandle coreHandle, [MarshalAs(UnmanagedType.LPArray)] byte[] link, refExceptionStruct ex);
}
}
5. MediaPlayerHandle和MediaPlayer類
using System;
using System.Runtime.InteropServices;
namespace MyOwnPlayer
{
class MediaPlayerHandle : SafeHandle
{
//構造方法
public MediaPlayerHandle()
: base(IntPtr.Zero, true)
{
}
//重寫的方法
public override bool IsInvalid
{
get { return handle == IntPtr.Zero; }
}
protected override bool ReleaseHandle()
{
if (!IsInvalid)
{
libvlc_media_player_release(this);
handle = IntPtr.Zero;
}
return true;
}
protected override void Dispose( bool disposing)
{
ReleaseHandle();
base.Dispose(disposing);
}
//Dll動态導入
[DllImport( "libvlc")]
private static extern void libvlc_media_player_release(MediaPlayerHandle mediaPlayerHandle);
}
}
using System;
using System.Runtime.InteropServices;
namespace MyOwnPlayer
{
class MediaPlayer
{
//mediaPlayerHandle字段和屬性
private MediaPlayerHandle mediaPlayerHandle;
public MediaPlayerHandle MediaPlayerHandle
{
get { return mediaPlayerHandle; }
}
//構造方法
public MediaPlayer(MediaHandle mediaHandle, ref ExceptionStruct ex)
{
mediaPlayerHandle = libvlc_media_player_new_from_media(mediaHandle, ref ex);
}
//設定父視窗
public void VedioSetParent(CoreHandle coreHandle, IntPtr hDT, ref ExceptionStruct ex)
{
libvlc_video_set_parent(coreHandle, hDT, ref ex);
}
//播放
public void Play( ref ExceptionStruct ex)
{
libvlc_media_player_play(mediaPlayerHandle, ref ex);
}
//停止
public void Stop( ref ExceptionStruct ex)
{
libvlc_media_player_stop(mediaPlayerHandle, ref ex);
}
//Dll動态導入
[DllImport( "libvlc")]
private static extern MediaPlayerHandle libvlc_media_player_new_from_media(MediaHandle libvlc_media_handle, ref ExceptionStruct ex);
[DllImport( "libvlc")]
private static extern void libvlc_video_set_parent(CoreHandle coreHandle, IntPtr hDT, ref ExceptionStruct ex);
[DllImport( "libvlc")]
private static extern void libvlc_media_player_play(MediaPlayerHandle mediaPlayerHandle, ref ExceptionStruct ex);
[DllImport( "libvlc")]
private static extern void libvlc_media_player_stop(MediaPlayerHandle mediaPlayerHandle, ref ExceptionStruct ex);
}
}
6. 基本工作做好了。下一步建立一個Form,裡面畫一個Panel(播放容器),畫一個Textbox(播放位址),畫一個Button(播放按鈕),Button的點選事件為:
private void button1_Click(object sender, EventArgs e)
{
//要播放的檔案的uri
string uri = this.textBox1.Text;
//進行播放的控件的句柄
IntPtr hdl = this.panel1.Handle;
//播放參數
string[] argv = new string[] { "-I", "--ignore-config" };
//vlc對象的建立
ExceptionStruct ex = new ExceptionStruct();
Core core = new Core(argv, ref ex);
Media media = new Media(core.CoreHandle, uri, ref ex);
MediaPlayer player = new MediaPlayer(media.MediaHandle, ref ex);
//垃圾回收
GC.Collect();
//播放
player.VedioSetParent(core.CoreHandle, hdl, ref ex);
player.Play(ref ex);
//繼續回收垃圾等相關操作
GC.Collect();
GC.WaitForPendingFinalizers();
} 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(...)接口的中文路徑轉碼處理
using System;
using System.Runtime.InteropServices;
namespace MyOwnPlayer
{
class Core
{
//coreHandle字段和屬性
private CoreHandle coreHandle;
public CoreHandle CoreHandle
{
get { return coreHandle; }
}
//構造方法
public Core( string[] argv, ref ExceptionStruct ex)
{
byte[][] argvbytes = new byte[argv.Length][];
for ( int i = 0; i < argv.Length; i++)
{
argvbytes[i] = Encoding.UTF8.GetBytes(argv[i]);
}
coreHandle = libvlc_new(argv.Length, ReturnIntPtr(argvbytes, argv.Length), ref ex);
}
//轉換函數
private IntPtr ReturnIntPtr( byte[][] data, int length)
{
IntPtr[] dataIntPtrArr = new IntPtr[length];
for ( int i = 0; i < length; i++)
{
dataIntPtrArr[i] = Marshal.AllocHGlobal(data[i].Length * sizeof( byte));
Marshal.Copy(data[i], 0, dataIntPtrArr[i], data[i].Length);
}
IntPtr dataIntPtr = Marshal.AllocHGlobal(length * Marshal.SizeOf( typeof(IntPtr)));
Marshal.Copy(dataIntPtrArr, 0, dataIntPtr, length);
return dataIntPtr;
}
//Dll動态導入
[DllImport( "libvlc")]
private static extern CoreHandle libvlc_new( int argc, IntPtr argv, ref ExceptionStruct ex);
}
} 補充二:本地存儲。 對libvlc_new的argv進行轉碼的主要目的就是為了進行本地存儲,由于要将存儲路徑傳入到argv中,是以要對中文的存儲路徑進行轉碼。下面的做法是将視訊流預設存儲為ts流,邊播放邊存儲。
//avPath是本地存儲路徑,需要注意路徑的/和/的問題。
argv = new string[] { "--sout=#duplicate{dst=display,dst=std{access=file,mux=ts,dst=" + avPath + "}}" };
//其他的就跟上一篇部落格一樣了。
core = new Core(argv, ref ex);
media = new Media(core.CoreHandle, link, ref ex);
player = new MediaPlayer(media.MediaHandle, ref ex);
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上就會顯示視訊了。這樣,一個簡單的點播系統就做好了。 請注意下面圖檔的視訊上的位址。
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
2
[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屬性,這樣就會避免拖動、最大化最小化及全屏還原時找不到圖像的缺陷。
2. 畫控件
畫四個控件,兩個靜态文本框,一個輸入框,一個按鈕。其中,第一個靜态文本框修改Caption為“路徑:”,第二個文本框為視訊的顯示區域,是以講ID改為IDC_DISPLAY,Caption去掉。輸入框關聯一個變量,CString類型,命名為m_path。按鈕的Caption改為“播放”,并為BN_CLICKED增加一個Function。在CMFCVLCdlg的構造方法中加入一下語句友善調試。
m_path = _T( "d:/01.avi"); // 輸入常用的視訊位址
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中建立檔案夾及導入上述檔案,最後入下圖所示。
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中加入頭檔案導入。
#include "vlc.h" 在button的onclick關聯函數中加入代碼:
void CMFCVLCDlg::OnButton1()
{
// TODO: Add your control notification handler code here
char path[100];
this->GetDlgItemText(IDC_EDIT1, path, 100);
libvlc_exception_t ex;
libvlc_exception_init(&ex);
int vlc_argc = 0;
char *vlc_argv[100];
vlc_argv[vlc_argc++] = "--ignore-config";
libvlc_instance_t *p_instance = libvlc_new(
vlc_argc, vlc_argv, &ex);
libvlc_media_t *p_media = libvlc_media_new(
p_instance, path, &ex);
libvlc_media_player_t *p_media_player
= libvlc_media_player_new_from_media(
p_media, &ex);
libvlc_drawable_t hwnd =
(libvlc_drawable_t) this->GetDlgItem(IDC_DISPLAY)->GetSafeHwnd();
libvlc_media_player_set_drawable(p_media_player, hwnd, &ex);
libvlc_media_player_play(p_media_player, &ex);
}
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中注釋掉:
#ifndef __intptr_t_defined
#define __intptr_t_defined
//typedef long intptr_t;
#endif
//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用的,嘻嘻),驅動安裝好後,在“我的電腦”中顯示如下。
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 成功後就可以看到了。切圖如下:
左邊的是攝像頭的流服務,右邊的是流的用戶端,從下邊的位址就能看的很清楚。 5. 遺留問題:
從圖檔可以看出,播放的視訊顔色是不對的,是攝像頭的問題還是vlc本身的問題還是參數設定的問題,現在不得而知,當然攝像頭本身是沒問題的,因為qq視訊都很正常。希望誰研究出來告訴我一聲。謝謝。 vlc的應用之十:vlc的遠端控制
VLC作為伺服器,可以進行遠端控制。再以前的部落格中提到用telnet配置VLM(《vlc的應用之七:用vlc做單點傳播,多點傳播及點播伺服器》),這也算是一種遠端控制。這次介紹的遠端控制主要包括以下兩種,使用的是vlc-1.0.5。
1. http遠端控制
2. vlc remote control (rc)
1. vlc的http遠端控制
指令行執行以下指令。
- vlc -I http --http-host=localhost:8866
解釋下:-I http就是啟用http服務。--host-host=ip:port為啟用的服務的ip位址及端口号。
浏覽器下輸入http://localhost:8866,會顯示如下界面。
點選左上角的open按鈕,打開input框。輸入路徑,點選play。出現視訊畫面。
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
指令行執行以下指令。
- vlc -I rc
出現vlc的rc背景。在裡面輸入help,列印出所有可以執行的指令。這些指令即為控制vlc的指令。如下圖所示。
輸入add d:/video/01.avi,則開始播放視訊。如下圖所示。
當然,我們也寫程式遠端控制vlc。主要思路就是建立一個socket,連接配接到vlc的rc服務,然後發送控制指令就可以了。
1) 指令行運作以下指令。
- vlc -I rc --rc-host=localhost:8888
解釋下:-I rc就是啟動rc服務,--rc-host=ip:host就是監聽的ip及端口号,一般ip設定為localhost。
2) 編寫程式client_vlc.c如下。
- /******************************************************************************
- * Filename: client_vlc.c
- * Created on: Apr 4, 2010
- * Author: jeremiah
- * Description: vlc的用戶端程式,測試vlc遠端控制
- *
- ******************************************************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #define MAXLINE 4096
- #define SERV_ADDR "127.0.0.1"
- #define SERV_PORT 8888
- int main(int argc, char *argv[]) {
- struct sockaddr_in servaddr;
- char buf[MAXLINE];
- int sockfd;
- int read_size;
- // 建立socket
- sockfd = socket(AF_INET, SOCK_STREAM, 0);
- bzero(&servaddr, sizeof(servaddr));
- servaddr.sin_family = AF_INET;
- inet_pton(AF_INET, SERV_ADDR, &servaddr.sin_addr);
- servaddr.sin_port = htons(SERV_PORT);
- // 建立連接配接
- connect(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
- // 向vlc發請求 "add d:/video/01.avi"
- write(sockfd, "add d:/video/01.avi/r/n",
- strlen("add d:/video/01.avi/r/n") + 1);
- // 列印vlc傳回結果
- read_size = read(sockfd, buf, MAXLINE);
- printf("Response from vlc:/n");
- printf("%s/n", buf);
- // 向vlc發請求 "is_playing"
- write(sockfd, "is_playing/r/n", strlen("is_playing/r/n"));
- // 列印vlc傳回結果
- read_size = read(sockfd, buf, MAXLINE);
- printf("Response from vlc:/n");
- printf("%s/n", buf);
- // 關閉socket
- close(sockfd);
- return 0;
- }
3) 編譯上面的程式,本文主要在Cygwin裡面編譯使用。
- gcc -o client_vlc client_vlc.c
4)執行程式,檢視結果。
可以看到從伺服器傳回的字元串,顯示添加成功,檢查播放情況顯示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了。效果圖如下: