2010年12月19日 星期日

在 Linux 以 VLC 搭配 Jtvlc 進行實況(第二彈)

由於之前利用 VLC 進行實況的方法會有延遲的問題,對於實況需要極低延遲的遊戲並不太合適。(尤其是動作類的遊戲,我想應該沒有人能接受畫面比你的輸入慢 300ms 吧 XD)

根據我自己的實驗,VLC的延遲是由 ALSA 錄音造成的。只要我在使用影像擷取裝置的時候啟用 ALSA錄音裝置,畫面就會 delay,delay 的時間長度和 VLC 的 ALSA 存取模組中的 cache 大小一樣。關掉錄音的話純轉播畫面是完全沒有延遲問題的。不幸的是,把 ALSA 的 cache 大小調低的話會讓聲音變得斷斷續續,資料也很難上傳到 Justin.tv,就算 kernel 有裝 ck 的 BFS patch 最多也只能把延遲降到 100多 ms。不過說也奇怪,如果 VLC 只播畫面,錄音由其他軟體(arecord)來做的話,畫面就不會 delay,錄音雖然有一點延遲但還可接受。因此我認為問題應該是出在 VLC。

今天我在嘗試其他方法解決這個問題時,發現 VLC 竟然有 window capture 的功能,而且經過測試,要錄 640x480@60fps 是完全沒問題的。因此我就想出了合併 MPlayer + VLC 的實況方法,用 MPlayer 去抓PSP的畫面,然後讓 VLC 去錄音並且抓 MPlayer 的輸出視窗。如此一來我們可以看 MPlayer 的視窗進行實況,然後 VLC 在背景負責錄音錄影。

以下是我用來擷取 PSP 影像的 MPlayer 指令:

$ mplayer tv:// -tv input=1:width=720:height=480:outfmt=yuy2  -vf pp=li,crop=480:274:124:106,scale=960:540,expand=960:540

這個指令會先將畫面做去交錯處理,然後進行畫面裁切,讓整個畫面符合 PSP 遊戲畫面的大小,最後畫面會放大兩倍,不然的話 480x272 解析度在 FullHD 的螢幕上看很難過。


下面的指令是讓 VLC 以視窗內容為目標去做串流,window:// 後面的十六進位數值是你的視窗 ID,你可以用 xwininfo這個指令去查詢。

vlc -vvv window://0x00000000  --input-slave=alsa://plughw:0,0  --sout='#transcode{vcodec=h264,vb=800,acodec=mp4a,ab=128,channels=2,samplerate=44100}:rtp{dst=127.0.0.1,port=1234,sdp=file://~/vlc.sdp}'


其他詳細的步驟則和上一篇一樣