關于流媒體開發的若干筆記

分類:技術 時間:2017-01-13

近期遇到項目,其中有在Android平臺播放rtsp流媒體的需求。整理若干資料如下,備查。

何謂流媒體

有別于傳統的視頻文件播放,流媒體是專門用于在網絡上傳輸的,采用所謂的 流式傳輸 方式。

既然在網絡上傳輸,就免不了有協議用來規定傳輸過程中的各個場景。流媒體的協議很多,經過前期選型,項目中采用了較為常用的RTSP協議。也曾經考慮過用RTMP協議,但考慮到RTSP的實時性要好于RTMP,更貼合項目需求,故而選擇了RTSP。

百度百科 的詞條里介紹的比較清楚了,在決定開發之前,最好先通讀一遍。

編碼器、服務器與解碼器

以近期火爆的直播為例,編碼器是指流媒體的采集端,如美女主播用的手機APP、游戲直播用的PC端軟件(如OBS)等。編碼器將攝像頭、屏幕或具體的視頻文件,處理成流媒體特定的格式發往服務器。而項目中使用的則是專門的硬件編碼器,作用是將HDMI傳輸的視頻流編碼成網絡信號傳給服務器。

服務器起到中轉的作用,一方面接收編碼器的推送,另一方面負責向單個或多個解碼器分發視頻流。當然,很多時候還會有存儲功能。

解碼器就是用來播放視頻流的,如各類視頻播放器。

常見的解決方案

VLCFFmpeg 是最為常用的開源跨平臺的音視頻流解決方案。 live555 是一個為流媒體提供解決方案的跨平臺的C 開源項目,據說是為VLC提供了視頻播放方案,由于沒有官方的Android支持,故而未曾深入研究。

對編碼器而言,常見的 OBS 可以支持win、mac、Linux三大平臺,Android上有 libstreaming ,而iOS未曾深入研究。當然,還有前面提到的專門的編碼器設備。

服務器的解決方案主要有(引自 知乎李楊的回答

  • 流媒體解決方案 Live555 (C )
  • 流媒體平臺框架 EasyDarwin (C ,國產精品)
  • 實時流媒體播放服務器程序DarwinStreamingSrvr (C )
  • Flash流媒體服務器 Red5 (Java)
  • 流媒體服務器 Open Streaming Server (Java)
  • FMS流媒體服務器 (Adobe,收費的)
  • Wowza流媒體服務器(Java)
  • 開源流媒體平臺FreeCast(Java)
  • Nginx RTMP插件(可以走走歪門邪道)

開放的直播平臺也不失為一種快速解決方案,如 目睹直播 (親測,無需認證或充值即可測試)、 樂視云視頻 (資質認證一直未能通過)等。一些直播方面的知識也可從這些網站上獲取。

國內的開發者平臺,如 阿里云的視頻直播百度云的音視頻直播LSS 等,是無需自己搗騰服務器軟件、而又可自主掌控直播的另一種途徑。并且,作為開發者平臺的產物,要比普通直播平臺提供了更為開放的接口和擴展能力。

此外, mplayerffdshow 提供了開源的解碼器方案,但相對復雜。 vitamio 支持Android和iOS,是國產媒體播放領域的翹楚。需要注意的是,vitamio對于企業商用是需要授權的,但 官網提到的執行周期 是14年底,也算是對混亂的國內知識產權領域的一種冷嘲吧。

使用vitamio播放rtsp遇到的問題

vitamio官網官方github 的版本較亂,但好在使用并不復雜。

從官網下載vitamio20160930.zip,加壓后有 InitActivityVitamioListActivity 兩個文件夾,后面這個目測用不到,在AndroidStudio中將前者引入成Module,并在原項目Module中增加 InitActivity 的依賴。

接下來的開發中遇到了些許問題,記錄如下。

  • 無法固定外框大小

    單獨的使用 io.vov.vitamio.widget.VideoView 插件,即使在xml中設置了高和寬,或者在代碼中動態設置,均無法生效。下面是一個無效的例子:

lt;io.vov.vitamio.widget.VideoView   
  android:id=quot;@ id/surface_viewquot;   
  android:layout_width=quot;280dpquot;  
  android:layout_height=quot;210dpquot;  
  android:layout_centerHorizontal=quot;truequot; 
  android:layout_centerVertical=quot;truequot; /gt;
  • 動態調整外框大小后無法正確顯示

    網上一般的寫法,是在 io.vov.vitamio.widget.VideoView 外面包裹一層 io.vov.vitamio.widget.CenterLayout ,這對于意圖在代碼中動態調整外框的需求是無效的。

    同時,記得在調整大小后,調用

    videoView.setVideoLayout(VideoView.VIDEO_LAYOUT_FIT_PARENT, 0);

    經過嘗試,下面的做法是可行的:

lt;RelativeLayout
    android:padding=quot;4dpquot;
    android:layout_width=quot;wrap_contentquot;
    android:layout_height=quot;wrap_contentquot;
    android:background=quot;@drawable/bg_videoquot;gt;

    lt;io.vov.vitamio.widget.VideoView
        android:id=quot;@ id/surface_viewquot;
        android:layout_width=quot;280dpquot;
        android:layout_height=quot;210dpquot;
        android:layout_centerHorizontal=quot;truequot;
        android:layout_centerVertical=quot;truequot; /gt;

lt;/RelativeLayoutgt;
  • 透屏及花屏問題

    項目中是在百度地圖上層放置一個VideoView播放視頻,而實際使用中發現,啟動后,VideoView不顯示;而將地圖層先隱藏再手動顯示后,會出現花屏現象,且顯示極不清晰。

    網上介紹的 兩種方法 在我的項目中并沒能生效:

    1. vitamio插件的io.vov.vitamio.widget.VideoView.java
        152行 surfaceCreated函數,加入一行代碼搞定
        mSurfaceHolder.setFormat(PixelFormat.RGBX_8888);
    2. AndroidManifest.xml文件中,播放器的Activity主題背景修改為
        android:theme=quot;@android:style/Theme.Translucent.NoTitleBar.Fullscreenquot;

    據查,原因應該是VideoView啟動后,默認至于最下層。

    修改VideoView.java源碼,在initVideoView函數中任意地方增加如下代碼即可:

    setZOrderOnTop(true);
  • 無法響應click事件

    項目需求是在VideoView上單擊后變大,再次單擊后返回原始狀態。

    而setOnClickListener后,發現點擊事件不會被觸發。

    原因是VideoView.java中的onTouchEvent將事件“消化”掉了,修改即可。

@Override
    public boolean onTouchEvent(MotionEvent ev) {
        if (isInPlaybackState()  mMediaController != null)
            toggleMediaControlsVisiblity();
        //return false;
        return super.onTouchEvent(ev);
    }

Tags: 安卓開發

文章來源:http://www.jianshu.com/p/01b78fa5d3bb


ads
ads

相關文章
ads

相關文章

ad