2016年8月28日 星期日

在老舊電腦上跑 vlc streaming 服務

該怎樣調校 vlc 的參數, 才可以把老舊電腦變成監視錄影器 (audio & video streaming server) 呢? 這篇延續 「循序漸進的 vlc 命令列教學」 第七節, 一樣拿一部舊筆電透過網路攝影機當作 vlc streaming server, 讓它在客廳看電視; 又在書房同一個區網內用一部 PC 連到筆電透過筆電間接看電視。 這篇的重點是如何用最懶惰的方法調參數, 讓不夠力的老舊筆電 (藉由犧牲畫質, 甚至犧牲聲音) 也能勉強播放。 [注意: 本文指令皆無加密效果; 請不要在公開網路上播放洩漏隱私或有著作權限制的內容!]

一、 降低網路及客戶端的不確定性

影音串流失敗, 經常是因為速度/效能不足的問題。 所以第一個要點就是先排除網路速度的問題: 請先在區網做實驗就好, 確保網路速度不是瓶頸。

再來, 接收影音的客戶端 (書房 PC) 相對來說比較不太需要強大的運算力。 (這跟 「解壓縮檔案比壓縮要輕鬆快速」 的道理一樣。) 所以如果無法播影片, 多半需要從串流伺服器那一頭去改設定, 而不是在客戶端這頭。

mplayer 的警告訊息 至於在客戶端這頭... vlc 印出來的錯誤訊息很難理解, 甚至連 google 大神都找不太到好答案。 後來我都改用 mplayer 來測試, 至少它的錯誤訊息比較容易理解。 指令如下: mplayer http://192.168.12.34:5780 如果它印出來的 "cache fill" 一直卡在 "0.00%" 那麼比較有可能是串流伺服器那頭的問題, 請停掉伺服器, 改其他參數重來一次。 有時 mplayer 填了一部分的 cache 之後, 會開始抱怨 「cache empty」, 請不要按 ctrl-c 打斷它! 也並不需要如它建議提高 -cache 跟 -cache-min 的值, 只需要 很有耐心地等幾分鐘, 影像就會出現了。

[9/1] ffmpeg 套件裡面的 ffplay 指令的錯誤訊息也很清楚, 而且成功率比 mplayer 高、 等待時間比 mplayer 短。

mplayer 測試成功之後, 如果需要, 客戶端再改用 vlc 或其他播放軟體。

二、 減輕伺服器負擔的方法

再來談伺服器端 (筆電) 的設定。 在筆電上記得要另開一個分頁或視窗, 用 top 指令隨時監看 CPU 使用率。 最好只有 cvlc 一個程序吃最兇, 而且筆電的 load average 最好經常保持在 1.00 以下。 比方說, 因為我都從 PC 用 ssh -X 連到筆電操作, 所以用一陣子之後, 發現筆電上的螢幕保護程式就跑出來亂, 吃掉不少資源。

影音參數又多又複雜, cvlc 命令列參數調校到快哭出來; 還好發現 ffmpeg 的 h264 編碼器 有幾組預先打包好的 「參數套餐集」 (preset), 讓我們這些弱弱的凡人可以指定速度就好, 剩下的細節它自動幫我們填。 如果你的舊電腦不夠力, 預設的 medium 參數套餐集將無法即時提供影音串流給客戶端。 這時可以改用 fast、 faster、 veryfast、 superfast 甚至是最快的 ultrafast, 犧牲品質換取速度。 想知道每組 preset 到底設定了哪些參數? x264 原始碼 解壓縮後, 在 common/common.c 裡面可以看到 (天書 orz)。

查看 VLC 的 streaming features list 各種屬性/格式的相容對照表, 從 H.264/MPEG-4 那一列看過去, 並且了解一下 Transport Stream 的意義 之後, 決定那就採用 TS 當容器格式吧。

網路上有很多複雜的指令, 有些可能也是抄來的, 連作者自己都不知道是什麼意思 :-) 我則傾向盡量不要用看不懂的參數。 要調整參數之前, 建議先 用 mediainfo 查看你的影片檔案庫, 看看每個參數的正常值大約是多少。 比方說, 我發現手邊大部分影片的 bitrate 落在 200k bps 到 600k bps 之間, 而大部分聲音的 bitrate 則落在 40k 到 150k 之間。 但是 打電話品質的 audio bitrate 其實低到 10k 都還可以接受。 所以如果要調降 vb (video bitrate) 跟 ab (audio bitrate) 的話, 合理的低值是 vb=200 及 ab=10。 不過實驗後發現: 降低這兩個值, 對於伺服器減壓效果似乎有限。 不解的是, 降低 fps (每秒畫面數) 效果好像也有限? 而且這些數值改成超誇張低值時, 反而會出現其他奇奇怪怪的問題, 甚至提高接收端的失敗率。

另一個減壓效果很好的設定, 是降低解析度。 例如在原先預設的 640x480 模式底下, top 指令看到 vlc 吃掉五六十趴的 CPU, 改成 160x120 模式之後, 掉到只剩二十幾趴。

當然, 最好直接指定網路攝影機硬體所支援的解析度, 避免再多一次轉換。 請安裝 v4l-utils 套件, 然後用 v4l2-ctl --list-formats-ext 指令就可以查看你的攝影機到底支援哪些解析度。

[9/1] eeepc 700 採用 mux=ts 換各種參數都失敗; 後來改用 mux=ogg 就成功出現影像了! vcodec=mjpg 的效果比 vcodec=theora 要流暢。 至於聲音怎麼樣都試不出來。 結論: vcodec=mjpg 加 mux=ogg 搭配低解析度, 目前看來是舊電腦的最佳組合。

三、 機器、 OS、 指令

以下是我的實驗筆記。

  1. 2011 年的 聯想 x220i, lubuntu 15.04: 這個陽春指令成功送出影音串流: cvlc v4l2:// :v4l-vdev=/dev/video0 :input-slave=alsa:// :sout='#transcode{vcodec=x264,venc=x264{preset=veryfast},acodec=mpga} : std{access=http, mux=ts, dst=:5780}'
  2. 2008 年的 華碩 eeepc 900HA, antix 16: 不論怎麼調整, 聲音總是會超 lag, 最後放棄聲音, 只送出影像: cvlc v4l2:// :v4l-vdev=/dev/video0 :input-slave=alsa:// :sout='#transcode{vcodec=x264,venc=x264{preset=superfast},acodec=mpga} : std{access=http, mux=ts, dst=:5780}'
  3. 2007 年的 華碩 eeepc 700, antix 16: 有影像沒有聲音: cvlc v4l2:// :v4l-vdev=/dev/video0 :input-slave=alsa:// :sout='#transcode{vcodec=mjpg} : std{access=http, mux=ogg, dst=:5780}'
  4. 2004 年的 華碩 z9100: 裝完 antix 16 進 X Window 時全黑; lubuntu 15.04 抓不到 webcam; 改用 usb 網路攝影機, 執行 cvlc 時發生 Floating point exception。 好吧, 我放棄了。
  5. 一個複雜的指令, 展示如何指定其他參數: (解析度 160x120, 每秒 10 張圖, video bitrate 200k, audio bitrate 12k) cvlc v4l2:// :v4l-vdev=/dev/video0 :input-slave=alsa:// :v4l2-width=160 :v4l2-height=120 :sout='#transcode{vcodec=x264,vb=200,fps=10,venc=x264{preset=ultrafast},acodec=mpga,ab=12} : std{access=http, mux=ts, dst=:5780}'
  6. 目前成功率最高的指令cvlc v4l2:// :v4l-vdev=/dev/video0 :input-slave=alsa:// :v4l2-width=160 :v4l2-height=120 :sout='#transcode{vcodec=mjpg,acodec=vorbis} : std{access=http, mux=ogg, dst=:5780}'

你的實驗成功嗎? 請留言分享一下你的電腦配備及 cvlc 參數吧!

1 則留言:

  1. 更新: (1) 在客戶端, ffplay 的成功率比 mplayer 更高。 (2) 在伺服器端, 目前成功率最高、效果最好的是 vcodec=mjpg 加 mux=ogg 搭配低解析度。

    回覆刪除