2014-02-28 82 views
19

我想知道是否可以在同一個佈局中使用兩個表面並在同一時間查看每個表面。將來我會使用視圖的網格視圖,但使用vlc的每個視頻視圖。android libvlc多表面問題

我使用fragment修改此示例(android-vlc-sample)。

結果是我只看到一個視頻......我該如何解決?

從日誌貓我看不到重要的錯誤,但我認爲有針對Android UIThread呈現問題

Java編碼

public class MultipleVideoPlayFragmentActivity extends FragmentActivity { 

public final static String LOCATION = "com.compdigitec.libvlcandroidsample.MultipleVideoPlayFragmentActivity.location"; 
private static final String TAG = "MediaPlayer"; 
public String mFilePatha; 

@Override 
public void onCreate(Bundle icicle) { 
    super.onCreate(icicle); 
    setContentView(R.layout.activity_multiple_video_play_fragment); 
    Intent intent = getIntent(); 
    mFilePatha = intent.getExtras().getString(LOCATION); 
} 

public static class VideoFragment extends Fragment implements 
     SurfaceHolder.Callback, IVideoPlayer { 
    public final static String TAG = "LibVLCAndroidSample/VideoActivity"; 

    public final static String LOCATION = "com.compdigitec.libvlcandroidsample.VideoFragment.location"; 

    private String mFilePath; 

    // display surface 
    private SurfaceView mSurface; 
    private SurfaceHolder holder; 

    // media player 
    private LibVLC libvlc; 
    private int mVideoWidth; 
    private int mVideoHeight; 
    private final static int VideoSizeChanged = -1; 

    /************* 
    * Activity 
    *************/ 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     return inflater.inflate(R.layout.sample, container, false); 
    } 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     // Receive path to play from intent 

     Log.d(TAG, "Playing back " + mFilePath); 
     mFilePath = ((MultipleVideoPlayFragmentActivity) getActivity()).mFilePatha; 
     // mFilePath="rtsp://192.168.4.125:554/0"; 
     // mFilePath="android.resource://it.nexera.visiamobile/raw/sample_mpeg4"; 
     mSurface = (SurfaceView) getView().findViewById(R.id.surface); 
     holder = mSurface.getHolder(); 
     holder.addCallback(this); 
    } 

    @Override 
    public void onConfigurationChanged(Configuration newConfig) { 
     super.onConfigurationChanged(newConfig); 
     setSize(mVideoWidth, mVideoHeight); 
    } 

    @Override 
    public void onResume() { 
     super.onResume(); 
     createPlayer(mFilePath); 
    } 

    @Override 
    public void onPause() { 
     super.onPause(); 
     releasePlayer(); 
    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     releasePlayer(); 
    } 

    /************* 
    * Surface 
    *************/ 

    public void surfaceCreated(SurfaceHolder holder) { 
    } 

    public void surfaceChanged(SurfaceHolder surfaceholder, int format, 
      int width, int height) { 
     if (libvlc != null) 
      libvlc.attachSurface(holder.getSurface(), this); 
    } 

    public void surfaceDestroyed(SurfaceHolder surfaceholder) { 
    } 

    private void setSize(int width, int height) { 
     mVideoWidth = width; 
     mVideoHeight = height; 
     if (mVideoWidth * mVideoHeight <= 1) 
      return; 

     // get screen size 
     int w = getActivity().getWindow().getDecorView().getWidth(); 
     int h = getActivity().getWindow().getDecorView().getHeight(); 

     // getWindow().getDecorView() doesn't always take orientation into 
     // account, we have to correct the values 
     boolean isPortrait = getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT; 
     if (w > h && isPortrait || w < h && !isPortrait) { 
      int i = w; 
      w = h; 
      h = i; 
     } 

     float videoAR = (float) mVideoWidth/(float) mVideoHeight; 
     float screenAR = (float) w/(float) h; 

     if (screenAR < videoAR) 
      h = (int) (w/videoAR); 
     else 
      w = (int) (h * videoAR); 

     // force surface buffer size 
     holder.setFixedSize(mVideoWidth, mVideoHeight); 

     // set display size 
     LayoutParams lp = mSurface.getLayoutParams(); 
     lp.width = w; 
     lp.height = h; 
     mSurface.setLayoutParams(lp); 
     mSurface.invalidate(); 
    } 

    @Override 
    public void setSurfaceSize(int width, int height, int visible_width, 
      int visible_height, int sar_num, int sar_den) { 
     Message msg = Message.obtain(mHandler, VideoSizeChanged, width, 
       height); 
     msg.sendToTarget(); 
    } 

    /************* 
    * Player 
    *************/ 

    private void createPlayer(String media) { 
     releasePlayer(); 
     try { 
      if (media.length() > 0) { 
       Toast toast = Toast.makeText(this.getActivity(), media, 
         Toast.LENGTH_LONG); 
       toast.setGravity(
         Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0); 
       toast.show(); 
      } 

      // Create a new media player 
      libvlc = LibVLC.getInstance(); 
      libvlc.setHardwareAcceleration(LibVLC.HW_ACCELERATION_DISABLED); 
      libvlc.setSubtitlesEncoding(""); 
      libvlc.setAout(LibVLC.AOUT_OPENSLES); 
      libvlc.setTimeStretching(true); 
      libvlc.setChroma("RV32"); 
      libvlc.setVerboseMode(true); 
      // LibVLC.restart(this.getActivity()); 
      EventHandler.getInstance().addHandler(mHandler); 
      holder.setFormat(PixelFormat.RGBX_8888); 
      holder.setKeepScreenOn(true); 
      MediaList list = libvlc.getMediaList(); 
      list.clear(); 
      list.add(new Media(libvlc, LibVLC.PathToURI(media)), false); 
      libvlc.playIndex(0); 
     } catch (Exception e) { 
      Toast.makeText(this.getActivity(), "Error creating player!", 
        Toast.LENGTH_LONG).show(); 
     } 
    } 

    private void releasePlayer() { 
     if (libvlc == null) 
      return; 
     EventHandler.getInstance().removeHandler(mHandler); 
     libvlc.stop(); 
     libvlc.detachSurface(); 
     holder = null; 
     libvlc.closeAout(); 
     libvlc.destroy(); 
     libvlc = null; 

     mVideoWidth = 0; 
     mVideoHeight = 0; 
    } 

    /************* 
    * Events 
    *************/ 

    private Handler mHandler = new MyHandler(this); 

    private static class MyHandler extends Handler { 
     private WeakReference<VideoFragment> mOwner; 

     public MyHandler(VideoFragment owner) { 
      mOwner = new WeakReference<VideoFragment>(owner); 
     } 

     @Override 
     public void handleMessage(Message msg) { 
      VideoFragment player = mOwner.get(); 

      // SamplePlayer events 
      if (msg.what == VideoSizeChanged) { 
       player.setSize(msg.arg1, msg.arg2); 
       return; 
      } 

      // Libvlc events 
      Bundle b = msg.getData(); 
      switch (b.getInt("event")) { 
      case EventHandler.MediaPlayerEndReached: 
       player.releasePlayer(); 
       break; 
      case EventHandler.MediaPlayerPlaying: 
      case EventHandler.MediaPlayerPaused: 
      case EventHandler.MediaPlayerStopped: 
      default: 
       break; 
      } 
     } 
    } 
} 

} 

XML編碼

<?xml version="1.0" encoding="utf-8"?> 

<fragment 
    android:id="@+id/video_1_fragment" 
    android:layout_width="100dp" 
    android:layout_height="0dp" 
    android:layout_weight="1" 
    class="com.compdigitec.libvlcandroidsample.MultipleVideoPlayFragmentActivity$VideoFragment" /> 

<fragment 
    android:id="@+id/video_2_fragment" 
    android:layout_width="100dp" 
    android:layout_height="0dp" 
    android:layout_weight="1" 
    class="com.compdigitec.libvlcandroidsample.MultipleVideoPlayFragmentActivity$VideoFragment" /> 

單一片段佈局

<LinearLayout 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:baselineAligned="false" 
android:orientation="vertical" 
tools:context=".SampleActivity" > 

<FrameLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

    <SurfaceView 
     android:id="@+id/surface" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" 
     android:layout_gravity="center" /> 
</FrameLayout> 
+0

我在後臺服務有同樣的問題,我試過運行LibVLC的多個實例,但這不起作用,只播放了最後一個流。你解決了多個片段的問題? – Hpsaturn

+1

不,Vlc for android不支持多個實例,但我知道vlc員工正在爲此工作。檢查官方vlc開發人員論壇。 – tulkas85

+0

您好@ tulkas85: - 我面臨同樣的問題。我嘗試使用此鏈接 - [Android VLC播放器與多個實例](https://github.com/dariobanfi/multiplevlc)它工作正常與android 5.0但6.0渲染issue.means流得不到適當的。有些閃爍在那裏。 –

回答

0

請試試這個:

--- libvlc = LibVLC.getInstance(); 
+++ libvlc = new LibVLC(); 

附:你正在使用什麼版本的LibVLC-android?

P.P.S. example