iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 20
0
自我挑戰組

M157q 的待業程式生活日誌系列 第 20

[2018 iThome 鐵人賽] Day 20: 如何在 Linux 上使用 Miracast


TL;DR

先說結論,試了以下兩個專案:


前言

2017 年 5 月換租屋處後,客廳有台螢幕,雖然不大,但至少比筆電的螢幕還大。想說有時候筆電或手機可以把畫面投到上面用大螢幕看比較爽,然後又懶的接有線的 VGA 或 HDMI,就想說來買個無線投影裝置。

於是就在 6 月初左右就上網買了便宜的無線投影裝置,該裝置對於 iOS 裝置的支援是使用 DLNA,對於 Android 裝置的支援則是使用 Miracast,當時是我第一次知道 Miracast。

想說筆電是跑 Arch Linux,和 Android 一樣都是 based on Linux,所以應該也可以使用 Miracast 吧?才發現可以用的東西少的可憐,也不一定會動。在 GitHub 上找到了 2 看起來比較有希望的專案,花了好幾個小時,看程式碼、查閱相關文件,終於成功把筆電的畫面透過 Miracast 無線投影到螢幕上。

後來因為室友買了個攜帶型投影機送了 Chromecast 之後就沒有使用 Miracast 了,所以這篇算是個半殘文,但還是想紀錄一下,畢竟花了不少時間研究。


關於 Miracast

  • 可以把它想像成用 Wi-Fi 來傳輸 HDMI 訊號,所以可以不用接線就能把畫面投影到其他有支援 Miracast 的裝置上。
  • 除了不用接線外,也不需要有其他的裝置或是要連接到某個 Wi-Fi Access Point。
    • 這點真的很方便啊,不用買其他裝置就能支援無線投影。
  • 2012 底,由 Wi-Fi Alliance 推出,也是 Android 4.2 的重要新功能之一,但在 2015 年推出的 Android 6.0 卻消失了。
  • Miracast 不知道為啥一直沒有成為標準。
  • Google 後來推出了 Chromecast,基本上這裝置的功能完全和 Miracast 衝突,而且我覺得沒有比較好,除了得額外多接一個 Chromecast 以外,Chromecast 還需要一個額外的 Wi-Fi Access Point,更別說 Chromecast 實際使用上的體驗真的是頗差的。
  • 關於 Miracast 詳細介紹,可以參考這篇繁體中文的文章:以鏡射與Wi-Fi技術為基礎 Miracast實現多螢影音串流 - 技術前瞻 - 新通訊元件雜誌

紀錄

因為 MiracleCast 沒試成功,所以只會以紀錄 WDS 為主。
其實還有找到一個 openwfd,不過因為看起來已經年久失修了,所以就沒去試了。


WDS 的裝置分類

首先,WDS 把使用 Miracast 的裝置區分為以下兩種:

  • Sink: 要呈現畫面的裝置。
  • Source: 要把畫面投影出去的裝置。

我使用 WDS 時遇到的問題

然後把當時遇到的問題相關連結都先列出來一下:


WDS 安裝與使用步驟

WDS 會用到以下幾個程式,必須預先安裝:

  • wpa_supplicant
    • 2.4 以後的版本,且必須要在 build 的時候開啟 CONFIG_P2P=y, CONFIG_WIFI_DISPLAY=y, CONFIG_CTRL_IFACE_DBUS_NEW=y 這 3 個參數
  • connman
    • 必須是 1.28 以後的版本
  • gstreamer

接下來就可以照著以下步驟來嘗試:

diff --git a/mirac_network/mirac-gst-test-source.cpp b/mirac_network/mirac-gst-test-source.cpp  
index 12c2623..821e38a 100644  
--- a/mirac_network/mirac-gst-test-source.cpp  
+++ b/mirac_network/mirac-gst-test-source.cpp  
@@ -42,7 +42,9 @@ MiracGstTestSource::MiracGstTestSource (wfd_test_stream_t wfd_stream_type, std::  
     } else if (wfd_stream_type == WFD_TEST_VIDEO) {  
         gst_pipeline = "videotestsrc ! videoconvert ! video/x-raw,format=I420 ! x264enc ! mpegtsmux ! rtpmp2tpay ! udpsink name=sink " + hostname_port;  
     } else if (wfd_stream_type == WFD_DESKTOP) {  
-        gst_pipeline = "ximagesrc ! videoconvert ! video/x-raw,format=I420 ! x264enc tune=zerolatency ! mpegtsmux ! rtpmp2tpay ! udpsink name=sink " + hostname_port;  
+        gst_pipeline = "ximagesrc use-damage=0 ! videoscale ! videoconvert ! video/x-raw,format=I420,width=1440,height=900,framerate=50/1 ! x264enc aud=false bitrate=2048 dct8x8=true vbv-buf-capacity=1000 tune=stillimage+zerolatency byte-stream=true ! video/x-h264,profile=high ! muxer. pulsesrc device=alsa_output.pci-0000_00_1b.0.analog-stereo.monitor ! audioconvert ! audio/x-raw,channels=2,rate=44100 ! faac ! audio/mpeg,mpegversion=4 ! muxer. mpegtsmux name=muxer alignment=0 ! rtpmp2tpay pt=33 ! udpsink name=sink sync=false " + hostname_port;  
  • cmake .
  • make
  • sudo wpa_supplicant -i wlp0s20u1 -ddt -u
    • wlp0s20u1 請換成你的無線網卡裝置名稱
    • -ddt: 用來開啟比較詳細的 debug 訊息,且在訊息加上 timestamp
    • -u : 用來開啟 DBus control interface
      • 如果 wpa_supplicant 在編譯的時候沒有加入上面提到的 CONFIG_CTRL_IFACE_DBUS_NEW=y 的話,這個選項就不會有用。
    • 執行這行指令的時候最好是先把原本有在用的 network manager 關掉,避免衝突。
  • sudo connmand -r -n -d -i wlp0s20u1
    • wlp0s20u1 請換成你的無線網卡裝置名稱
    • -r: 不要開啟 DNS proxy
      • 官方的 README 上沒有加這個選項,是我自己加上去的,我記得當時可以解掉一些問題,但現在忘了是什麼問題了。
    • -n: 不要在背景執行,方便看到 debug 訊息
    • -d: 開啟 debug 模式
  • sudo connmanctl
    • 開啟 connman 的互動式介面
  • connmanctl> enable wifi
  • connmanctl> enable p2p
    • connmanctl> scan p2p
    • connmanctl> peers
    • 檢查 p2p 功能是否正常
  • connmanctl> agent on

如果以上都正常的話,應該就會像官方在其 GitHub repo 的 wiki 所列出的截圖一樣:

  • Android 手機要無線投影到電腦 (Sink mode)
    • 打開 Miracast 選單應該就可以看到電腦裝置
    • 選擇投影到電腦上
    • 許可連線
    • 沒問題的話應該就可以在電腦上跳出一個視窗顯示手機的畫面了
  • 電腦要無線投影到其他裝置 (Source mode)
    • connmanctl> scan 可以重新掃描附近的裝置
    • connmanctl> peers 列出可以連線的裝置
    • connmanctl> connect N 連線到該裝置
    • 許可連線
    • 正常的話其他裝置應該就會顯示電腦上的畫面了

結論

還沒到完全能動,畫面有點卡,而且沒有聲音,猜測是還得去調整 gstreamer 的參數。

但就紀錄下來,也給可能有遇到這個問題想要解決的人參考,如果有幫助到你的話很歡迎留言跟我說一下,如果試出了更好的結果當然更棒就是。


參考來源


如果覺得我的文章不錯的話,
請幫我按讚、追蹤、訂閱、留言、分享,
有任何問題也都歡迎留言討論,
也可以利用像是 Feedly 等 RSS Reader,
直接訂閱我的部落格:https://blog.m157q.tw
iThome 這邊我應該只有鐵人賽的時候會使用。


上一篇
[2018 iThome 鐵人賽] Day 19: 關於 Django REST framework 的一些筆記
下一篇
[2018 iThome 鐵人賽] Day 21: 我平常在電腦上用了哪些程式
系列文
M157q 的待業程式生活日誌31

尚未有邦友留言

立即登入留言