音影片直播技術--影片畫中畫
- 2020 年 4 月 2 日
- 筆記

多影片
前言
大家好,今天我為大家介紹一下如何在Android系統下實現實時直播互動中的多影片展示功能。 我們現在都清楚實時直播互動中多路影片的展示是目前比較流行的趨勢,因為大家都想看到更多影片畫面的需求,是非常符合人類的習慣的。
大家都知道,在Android系統下顯示影片主要有三種View,分別是SurfaceView、GLSurfaceView及TextureView。它們的區別大家可以看我的另一篇文章 影片的渲染與展示 一文的介紹。我們今天這個例子是通過 SurfaceView來給大家演示的。
基本流程
在這個項目中使用了兩個SurfaceView,一個SurfaceView作為Camera攝影機預覽View,另一個SurfaceView用於Player View。Camera preview的大小與螢幕大小相同,並把它作為背景,而Player View是一個小窗口,它浮在 Camera preview的上面,用戶可以在螢幕內任意的拖動它。
注意,之所以我們在這個項目中使用 SurfaceView,主要是因為SurfaceView更為靈活,便於我們更好的控制它。當然它同時帶來的缺點是,與其它View相比開發變得比較複雜。
技術實現
在資源文件中定義兩個 SurfaceView
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/main" tools:context="com.daka.live.multisurfaceview.MainActivity"> <SurfaceView android:id="@+id/surfaceview1" android:layout_width="match_parent" android:layout_height="match_parent" /> <SurfaceView android:id="@+id/surfaceview2" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>
生成SurfaceView對象並設置屬性
我們在生成Player View時,要設置它的大小,位置及在頂層展示,否則它會被Camera preview覆蓋掉。
...... mSurfaceView1 = (SurfaceView)findViewById(R.id.surfaceview1); RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(320, 240); // set size params.setMargins(100, 50, 0, 0); // set position mSurfaceView2 = (SurfaceView)findViewById(R.id.surfaceview2); mSurfaceView2.setLayoutParams(params); //設置view大小 mSurfaceView2.setOnTouchListener(this); //用於拖動 sh = mSurfaceView2.getHolder(); sh.addCallback(this); sh.setFormat(PixelFormat.TRANSLUCENT); mSurfaceView2.setZOrderMediaOverlay(true); mSurfaceView2.setZOrderOnTop(true); //設置在最頂層展示 ......
實現OnTouch介面
- 添加 View.OnTouchListener 實現
public class MainActivity extends Activity implements View.OnTouchListener { }- 實現 onTouch 方法
public boolean onTouch(View view, MotionEvent event) { final int X = (int) event.getRawX(); final int Y = (int) event.getRawY(); switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: RelativeLayout.LayoutParams lParams = (RelativeLayout.LayoutParams) view.getLayoutParams(); mXDelta = X - lParams.leftMargin; mYDelta = Y - lParams.topMargin; break; case MotionEvent.ACTION_UP: break; case MotionEvent.ACTION_POINTER_DOWN: break; case MotionEvent.ACTION_POINTER_UP: break; case MotionEvent.ACTION_MOVE: RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) view.getLayoutParams(); layoutParams.leftMargin = X - mXDelta; layoutParams.topMargin = Y - mYDelta; layoutParams.rightMargin = -250; layoutParams.bottomMargin = -250; view.setLayoutParams(layoutParams); break; } mRoot.invalidate(); return true; }完整例子
多影片展示程式碼下載地址:https://github.com/garrylea/MultiSurfaceView

