HEXA娛樂開發日志技術點005——死而復生之Gstreamer推流

HEXA開發日志目錄
上一篇 HEXA娛樂開發日志技術點004——一步到位的推流


前言

距離上一次發文快4周了,不過我沒有偷懶,技術上確實遇到了點困難,反正情況變成了下面這樣,講完干貨再說。

這些折騰充分體現了技術視野對開發的重要性。

技術需求與技術點

干貨

很遺憾,上次的工作成果又被暫時拋棄了,這次我用Gstreamer
一切原因后面再解釋,先說說搞出了啥咋搞的為啥這么搞

搞出了啥

成功使用Gstreamer實現了推流,從網頁上看的性能,fps16左右,分辨率320x200,h264編碼,雖然參數慘不忍賭,但也比之前的fps不到4強了。目前還沒有整合到skill里面,只是用binary執行文件測試,源碼在github上。

咋搞的

  1. 登陸機器人
  2. 掛載優盤(優盤里有gst-plugins-good的git庫)
  3. 編譯+安裝gst-plugins-good
  4. 替換機器人身上的v4l2 gstreamer插件
  5. 編譯我寫的測試程序,生成binary執行文件simple
  6. 執行./simple <你的rtmp url>

為啥這么搞

下面逐條解釋一下上面步驟

  • 登陸機器人
    我之前好像提到過進到機器人身體里之類的動作,指的就是這個。操作方法是在手機APP上的Skill商店里打開高級開發模式,同時會看到ssh登陸命令,登陸后別忘了用passwd命令改一下初始密碼。一般終端都支持ssh,都可以直接登陸。
ssh root@<機器人IP地址>
  • 掛載優盤
    掛載優盤的原因是,機器人身上的空間不夠大,后面的編譯動作會占空間。如果不出意外,并且優盤是FAT32文件系統的話,掛載命令就是下面這個,然后/mnt/sda1就等同優盤的根目錄了。
mkdir /mnt/sda1
mount -t vfat dev/sda1 /mnt/sda1
  • 編譯+安裝gst-plugins-good并替換機器人身上的v4l2 gstreamer插件
    為啥要自己編譯這個東西呢?因為不弄的話,gstreamer程序會陷入死循環,為啥死循環呢,因為這機器人的kernel的v4l2驅動沒有按照官方標準實現,或者這版本的kernel這塊就是有問題的。他們這kernel不開源,我就只好從用戶層想辦法,所以就改了gst-plugins-good里面的v4l2相關代碼。
    編譯不麻煩,只是有幾個坑。
    執行./autogen.sh就會發現,有依賴的系統庫沒有裝,缺啥裝啥就行了,用apt命令解決,先執行apt search <缺少庫的名字>找到缺少庫的完整名字,然后apt install <缺少庫的完整名字>就行了。
    最后卡住的是gstreamer的版本問題,要把gst-plugins-good切換到tag1.2.0才能通過,生成Makefile,當然,這之前要apt install git裝一下git,或者在別處切好tag。
    在編譯和安裝完成后再替換一下系統原來的v4l2 gstreamer庫就可以了。
    這小節全部過程和命令如下
cd /mnt/sda1/gst-plugins-good
git checkout tags/1.2.0
git submodule init
git submodule update
./autogen.sh
報錯,形如fail...need ...xxx
apt search xxx
找到形如xxx-yyy
apt install xxx-yyy
./autogen.sh
再次執行,沒有報錯
make
make install
mv /usr/local/lib/gstreamer-1.0/libgstvideo4linux2.so /usr/lib/arm-linux-gnueabihf/gstreamer-1.0/libgstvideo4linux2.so

這之后可以考慮make uninstall卸掉它,因為需要的庫已經換完了,也沒必要占用空間。

疑似kernel的問題

有興趣的小伙伴可以去了解一下這個版本官方的的v4l2的VIDIOC_ENUMSTD ioctl返回值是不是有問題。機器人的kernel版本是下面這樣的

uname -a
Linux hexa 3.10.17_1.0.0_mb9000+ #35 SMP PREEMPT Thu Jan 18 07:08:48 UTC 2018 armv7l armv7l armv7l GNU/Linux

  • 我寫的測試程序
    關于這個步驟沒什么好解釋的,一個make,然后執行以下看看Usage就搞定。更需要說明的是為什么改用Gstreamer,至于這個程序大概怎么寫出來的,看Gstreamer的官方英文文檔是最好的,下面來講講為什么改用Gstreamer。

解惑

為什么改用Gstreamer

因為官方推薦
故事是這樣的,在上次的總結中有這樣一個問題:

下位機推流還有點問題,可以在播放端看到,似乎是推流的速度不夠,出現了視頻網站那種放一會兒就要緩沖一下的現象,具體原因有待分析

我針對這個問題研究了一番,發現官方的GO語言接口獲取一張圖像的時間是200多毫秒,大概是每秒4幀不到的樣子,后來我看到官方論壇上有提到用v4l2驅動直接訪問/dev/video0設備文件的方式,我試了發現,1280x720的圖就是每張200多毫秒,然后我向官方咨詢,就被安利了Gstreamer和他們集成到機器人身上的一個VPU硬件編碼模塊和基于它的Gstreamer插件。

這之后我就開始在Gstreamer和ffmpeg之間徘徊不前。

  • 一方面是因為我想不到還有什么比直接調用ioctl更直接的東西來獲得攝像頭的實際性能,這一方面在我偶然用網上的一個測試攝像頭的程序測試時發現了問題。這問題就是我一直測試的是1280x720尺寸的幀率,我在論壇上沒提到過我用的什么尺寸,結果我改成640x480后,就可以達到25幀了。我這一點結論還沒有得到官方的回復。
  • 另一方面因為搜索Gstreamer獲得的中文信息弄得我一頭霧水,越看越懵,所以還是想要延續原來的方案,想把官方安利的硬件編碼模塊搞成ffmpeg的一個編碼器,或者至少在較上層把他們對接起來,但是動起手來還是感覺很麻煩。最后下定決心,開始看Gstreamer的官方英文文檔,這下頭上的霧水沒了,一路搞下來才有今天這篇文章。

有趣的事

如果你不搞嵌入式,也許不會發現這件事很特別,那就是我的編譯是在機器人上完成的。經典的嵌入式開發套路是這樣的

上位機編譯,下位機運行

這個機器人違反了這個套路,它身上的開發環境一應俱全,只要不嫌編譯慢,它就既是上位機,又是下位機。


另一件有趣的事情是,機器人被我搞死一次。
那天我是把gstreamer工程(為啥編譯它?在這文章背后,我走的彎路多了。有人能歲月靜好,是因為有人在背后負重前行)放到機器人身上(不在優盤里)編譯,結果空間不夠了,我就刪了點東西,因為它總是報告/tmp目錄下創建東西不成功,我就把下面東西刪了,然后把優盤掛載到了/tmp,結果第二天我再開機就起不來了。后來我找到了說明書上重置的方法,要用6根線,把機器人背上的管腳按照說明書接一下,最后我到公司找了6根線把它救活了。
在清空/tmp時,下面有一個套接字文件,我比較懷疑是刪了它導致了機器人的死亡,但是我暫時不想驗證這個結論。

srwxr-xr-x  1 root root      0 May  8  2017 wpa_ctrl_698=

總結

  • 用Gstreamer實現了推流,暫時拋棄了ffmpeg
  • 發現機器人可以同時做上/下位機
  • 搞死一次機器人,重置救活
  • 音頻先不管,它不自帶話筒,一般的話筒它不能用,還得專門買,這事后面再研究吧
  • 目前推流的性能不是很好,不過先暫且如此吧,可以先整合進skill,然后研究一下怎么對視頻做圖像處理吧
  • 這些事情的草還沒發芽,包括彈幕命令集、機器人命名等
  • 也許會寫一篇關于Gstreamer的文章吧

下一篇 HEXA娛樂開發日志技術點006——日拱一卒拱歪了

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容