2011年6月22日 星期三

在 Linux 下使用 FFmpeg 進行實況

除了 VLC + jtvlc 這個組合之外,FFmpeg 也可以用來進行實況。而且 FFmpeg 不只可以用在 Justin.tv,連 Ustream 也可以上傳。正確的說是可以直接當 Adobe Flash Media Live Encoder 用。

FFmpeg 和 jtvlc 不同,你只需要給 FFmpeg 你的串流密鑰,不需要帳號名稱。以下是一個實況桌面的指令範例:

ffmpeg -f x11grab -s 640x480 -framerate 60 -i :0.0+300,300 -f alsa -ac 2 -i default -vcodec libx264 -vpre medium -s 640x480 -b 800k -bt 400k -acodec libfaac -ab 128k -threads 0 -f flv "rtmp://live.justin.tv/app/live_???????_???????? flashver=FMLE/3.0%20(compatible;\20FMSc/1.0)"

這個指令會擷取從螢幕左上角算起座標 300, 300 的地方,大小 640x480 的視窗內容,並且擷取 ALSA 的 default 裝置,格式為立體聲。輸出的視訊格式為 H.264,採用 medium preset 設定值,並使用固定位元率 800kbps、可容忍的變動範圍為 400kbps,音訊格式為 AAC,位元率 128kbps。後面 live_????????_???????? 就是你的串流密鑰,請參考前面 VLC + jtvlc 的文章取得你的密鑰。

如果你要在 Ustream 實況,那麼你得先到 Dashboard >> Manage My Channel >> Advanced Settings 下載給 FME 用的 xml 檔,裡面會寫需要的 url 和密鑰。要注意的是密鑰後面連著 offair 的字串,把那六個字元去掉才是真正的密鑰。

Ustream 的完整 url 大概長這樣:

rtmp://1.1234567.fme.ustream.tv/ustreamVideo/1234567/abcdefghijklmnopqrstuvwxyzABCDEF flashver=FMLE/3.0%20(compatible;\20FMSc/1.0)

1234567代表你的 channel code,密鑰則是大小寫英文加數字共32 bytes。

個人使用的經驗是覺得 FFmpeg 用來實況桌面的 CPU 使用率遠低於 VLC,VLC在擷取大畫面的時候會造成 Xorg 的使用率滿載並造成系統反應緩慢,FFmpeg在錄影的時候雖然也很吃 CPU,但是不會影響系統操作。

15 則留言:

  1. 到此一遊~

    找不到適當的留言處
    只好隨便回一篇

    VLC用的很頭痛
    看來該換換看了

    回覆刪除
  2. VLC 比 FFmpeg 吃 CPU,還有聲音延遲問題。FFmpeg 目前用起來比 VLC 穩定很多 XD Windows 那邊如果可以弄到虛擬 vfw 裝置的話應該也可以用來實況。

    回覆刪除
  3. 您好
    請問FFmpeg有沒有可能同時輸出實況至兩個網站?
    (例如 Jtv+ustream)

    先謝謝您

    回覆刪除
  4. FFmpeg 我沒試過,不過看起來 VLC 比較有可能做到同時輸出 orz

    回覆刪除
  5. 另外就是 FFmpeg 輸出到 Ustream 有時候會不明原因 crash,但是 Justin.tv run 多久都沒問題。結論是 ... Linux 實況真麻煩 XD

    回覆刪除
  6. 我今天嘗試在Windows上試看看FFmpeg

    不過google過後發現FFmpeg的Windows build不支援截取音訊 而截取視訊的部份我也沒試成功(可能是x64的關係)

    所以在實況上就沒搞頭了
    不過想想windows還有cygwin

    我對Linux和cygwin都不熟所以想問一下
    在cygwin上跑Linux版的FFmpeg然後照這篇方法有沒有機會呢?

    等比較空閒的時候我會試試看 不過還是先問一下可行性以免浪費時間XD

    回覆刪除
  7. 我想到一個方法。先用 ffmpeg 把實況的串流輸出到 stdout 然後導給另一個 ffmpeg 用 copy codec 去做多重輸出,這樣應該可以做到一次編碼多重輸出才對。

    回覆刪除
  8. 抱歉 Windows build 小弟不熟,照以前 Google 過的經驗是說 FFmpeg 只支援 x11grab 跟 vfw,x11grab要 X window,vfw 則是被廢棄的 video for windows API。至於 DirectShow 就不清楚了,有支援的話應該可以用虛擬 Webcam 之類的來做。

    回覆刪除
  9. 我在Linux上嘗試使用ffmpeg來上傳一個檔案,Justin.tv已經成功。Ustream則失敗在handshake。

    我嘗試使用您建議的RTMP地址,還是失敗。可以請您指教一下嗎?

    a003257@ubuntu:~/avm/ffmpeg/ffmpeg-0.8.7$ ./ffmpeg -debug 99 -i ~/Downloads/Sequence_01.mp4 -acodec copy -vcodec copy -f flv "rtmp://1.channel.fme.ustream.tv/ustreamVideo/channel/???????????????????????????????? flashver=FMLE/3.0%20(compatible;\20FMSc/1.0)"
    ffmpeg version 0.8.7, Copyright (c) 2000-2011 the FFmpeg developers
    built on Dec 8 2011 11:45:38 with gcc 4.4.3
    configuration: --disable-yasm
    libavutil 51. 9. 1 / 51. 9. 1
    libavcodec 53. 8. 0 / 53. 8. 0
    libavformat 53. 5. 0 / 53. 5. 0
    libavdevice 53. 1. 1 / 53. 1. 1
    libavfilter 2. 23. 0 / 2. 23. 0
    libswscale 2. 0. 0 / 2. 0. 0
    [mov,mp4,m4a,3gp,3g2,mj2 @ 0x95469a0] Format mov,mp4,m4a,3gp,3g2,mj2 probed with size=2048 and score=100
    [mov,mp4,m4a,3gp,3g2,mj2 @ 0x95469a0] ISO: File Type Major Brand: M4V
    [mov,mp4,m4a,3gp,3g2,mj2 @ 0x95469a0] All info found

    Seems stream 0 codec frame rate differs from container frame rate: 59.94 (60000/1001) -> 29.97 (2997/100)
    Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/a003257/Downloads/Sequence_01.mp4':
    Metadata:
    major_brand : M4V
    minor_version : 1
    compatible_brands: M4V mp42isom
    creation_time : 2011-12-09 14:06:21
    Duration: 00:09:34.41, start: 0.000000, bitrate: 789 kb/s
    Stream #0.0(eng), 10, 1/29970: Video: h264 (Main), yuv420p, 400x224 [PAR 1:1 DAR 25:14], 1001/60000, 692 kb/s, 29.97 fps, 29.97 tbr, 29970 tbn, 59.94 tbc
    Metadata:
    creation_time : 2011-12-09 14:06:21
    Stream #0.1(eng), 1, 1/44100: Audio: aac, 44100 Hz, stereo, s16, 93 kb/s
    Metadata:
    creation_time : 2011-12-09 14:06:21
    [rtmp @ 0x955bae0] Handshaking...
    [rtmp @ 0x955bae0] Server version 3.5.1.1
    [rtmp @ 0x955bae0] Proto = rtmp, path = /ustreamVideo/channel/???????????????????????????????? flashver=FMLE/3.0%20(compatible;\20FMSc/1.0), app = ustreamVideo, fname = channel/???????????????????????????????? flashver=FMLE/3.0%20(compatible;\20FMSc/1.0)
    rtmp://1.channel.fme.ustream.tv/ustreamVideo/channel/???????????????????????????????? flashver=FMLE/3.0%20(compatible;\20FMSc/1.0): Input/output error

    回覆刪除
  10. 我用自己的 gtk-fmle 前端去跑沒有遇到這個問題說 @@a

    回覆刪除
  11. 版主您好
    我只是簡單的想傳2個檔案(一個audio,一個video),利用ffmpeg合成mp4之後,在上傳到ustream,可是好像不像我想的這麼簡單,我的code如下
    ffmpeg -i test.h264 -i test.aac -f mp4 "rtmp://1.10813404.fme.ustream.tv/ustreamVideo/10813404/stream_key flashver=FMLE/3.0\20(compatible;\20FMSc/1.0)"
    然候就一直出現 Input/output error

    版主可以麻煩您給我一些建議嗎,感激不盡,謝謝

    回覆刪除
  12. 把 -f mp4 改成 flv 試試看吧,畢竟你上傳的位址是 Flash media server

    回覆刪除
  13. 盧先生您好~

    謝謝你的分享^^

    請問~我買電視筆 我要怎麼能再LINUX底下觀賞,並傳送至JUSTI TV

    感謝阿~~!!

    回覆刪除
  14. 盧先生您好@@

    謝謝你的文章~

    我想請教盧先生~如果我用電視筆再LINUX上觀看,我要如何把電視上傳到JUSTINTV呢@@?

    感謝阿~~!!

    回覆刪除
  15. 您好

    您可以先用 VLC 或者其他 player 播放電視畫面,然後再用本篇的方法上傳。

    由於需要錄系統聲音,所以推薦用 Pulseaudio(這個大部分桌面系統預設都有裝)

    來做 loopback。上傳的時候可以開 pavucontrol 來切換錄音來源(切到 monitor)。

    回覆刪除