0%

前言

  继续折腾vlc,做这个例子并不顺利,卡在只有声音没有图像这个问题好久,网上的例子有些API已经对不上,继续分享,,,

声明
  欢迎转载,但请保留文章原始出处:)
    博客园:http://www.cnblogs.com
    农民伯伯: http://over140.cnblogs.com

正文

  截图

    

  项目

    

  代码

复制代码

public class VlcVideoActivity extends Activity implements SurfaceHolder.Callback, IVideoPlayer { private final static String TAG = “[VlcVideoActivity]“; private SurfaceView mSurfaceView; private LibVLC mMediaPlayer; private SurfaceHolder mSurfaceHolder; private View mLoadingView; private int mVideoHeight; private int mVideoWidth; private int mVideoVisibleHeight; private int mVideoVisibleWidth; private int mSarNum; private int mSarDen;

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
    setContentView(R.layout.activity\_video\_vlc);

    mSurfaceView \= (SurfaceView) findViewById(R.id.video);
    mLoadingView \= findViewById(R.id.video\_loading); try {
        mMediaPlayer \= VLCInstance.getLibVlcInstance();
    } catch (LibVlcException e) {
        e.printStackTrace();
    }

    mSurfaceHolder \= mSurfaceView.getHolder();
    mSurfaceHolder.setFormat(PixelFormat.RGBX\_8888);
    mSurfaceHolder.addCallback(this);

    mMediaPlayer.eventVideoPlayerActivityCreated(true);

    EventHandler em \= EventHandler.getInstance();
    em.addHandler(mVlcHandler); this.setVolumeControlStream(AudioManager.STREAM\_MUSIC);
    mSurfaceView.setKeepScreenOn(true); // mMediaPlayer.setMediaList(); // mMediaPlayer.getMediaList().add(new Media(mMediaPlayer, "http://live.3gv.ifeng.com/zixun.m3u8"), false); // mMediaPlayer.playIndex(0);
    mMediaPlayer.playMRL("http://live.3gv.ifeng.com/zixun.m3u8");
}

@Override public void onPause() { super.onPause(); if (mMediaPlayer != null) {
        mMediaPlayer.stop();
        mSurfaceView.setKeepScreenOn(false);
    }
}

@Override protected void onDestroy() { super.onDestroy(); if (mMediaPlayer != null) {
        mMediaPlayer.eventVideoPlayerActivityCreated(false);

        EventHandler em \= EventHandler.getInstance();
        em.removeHandler(mVlcHandler);
    }
}

@Override public void onConfigurationChanged(Configuration newConfig) {
    setSurfaceSize(mVideoWidth, mVideoHeight, mVideoVisibleWidth, mVideoVisibleHeight, mSarNum, mSarDen); super.onConfigurationChanged(newConfig);
}

@Override public void surfaceCreated(SurfaceHolder holder) { if (mMediaPlayer != null) {
        mSurfaceHolder \= holder;
        mMediaPlayer.attachSurface(holder.getSurface(), this);
    }
}

@Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    mSurfaceHolder \= holder; if (mMediaPlayer != null) {
        mMediaPlayer.attachSurface(holder.getSurface(), this);//, width, height

} if (width > 0) {
mVideoHeight = height;
mVideoWidth = width;
}
}

@Override public void surfaceDestroyed(SurfaceHolder holder) { if (mMediaPlayer != null) {
        mMediaPlayer.detachSurface();
    }
}

@Override public void setSurfaceSize(int width, int height, int visible\_width, int visible\_height, int sar\_num, int sar\_den) {
    mVideoHeight \= height;
    mVideoWidth \= width;
    mVideoVisibleHeight \= visible\_height;
    mVideoVisibleWidth \= visible\_width;
    mSarNum \= sar\_num;
    mSarDen \= sar\_den;
    mHandler.removeMessages(HANDLER\_SURFACE\_SIZE);
    mHandler.sendEmptyMessage(HANDLER\_SURFACE\_SIZE);
} private static final int HANDLER\_BUFFER\_START = 1; private static final int HANDLER\_BUFFER\_END = 2; private static final int HANDLER\_SURFACE\_SIZE = 3; private static final int SURFACE\_BEST\_FIT = 0; private static final int SURFACE\_FIT\_HORIZONTAL = 1; private static final int SURFACE\_FIT\_VERTICAL = 2; private static final int SURFACE\_FILL = 3; private static final int SURFACE\_16\_9 = 4; private static final int SURFACE\_4\_3 = 5; private static final int SURFACE\_ORIGINAL = 6; private int mCurrentSize = SURFACE\_BEST\_FIT; private Handler mVlcHandler = new Handler() {
    @Override public void handleMessage(Message msg) { if (msg == null || msg.getData() == null) return; switch (msg.getData().getInt("event")) { case EventHandler.MediaPlayerTimeChanged: break; case EventHandler.MediaPlayerPositionChanged: break; case EventHandler.MediaPlayerPlaying:
            mHandler.removeMessages(HANDLER\_BUFFER\_END);
            mHandler.sendEmptyMessage(HANDLER\_BUFFER\_END); break; case EventHandler.MediaPlayerBuffering: break; case EventHandler.MediaPlayerLengthChanged: break; case EventHandler.MediaPlayerEndReached: //播放完成
            break;
        }

    }
}; private Handler mHandler = new Handler() {
    @Override public void handleMessage(Message msg) { switch (msg.what) { case HANDLER\_BUFFER\_START:
            showLoading(); break; case HANDLER\_BUFFER\_END:
            hideLoading(); break; case HANDLER\_SURFACE\_SIZE:
            changeSurfaceSize(); break;
        }
    }
}; private void showLoading() {
    mLoadingView.setVisibility(View.VISIBLE);
} private void hideLoading() {
    mLoadingView.setVisibility(View.GONE);
} private void changeSurfaceSize() { // get screen size
    int dw = getWindowManager().getDefaultDisplay().getWidth(); int dh = getWindowManager().getDefaultDisplay().getHeight(); // calculate aspect ratio
    double ar = (double) mVideoWidth / (double) mVideoHeight; // calculate display aspect ratio
    double dar = (double) dw / (double) dh; switch (mCurrentSize) { case SURFACE\_BEST\_FIT: if (dar < ar)
            dh \= (int) (dw / ar); else dw \= (int) (dh \* ar); break; case SURFACE\_FIT\_HORIZONTAL:
        dh \= (int) (dw / ar); break; case SURFACE\_FIT\_VERTICAL:
        dw \= (int) (dh \* ar); break; case SURFACE\_FILL: break; case SURFACE\_16\_9:
        ar \= 16.0 / 9.0; if (dar < ar)
            dh \= (int) (dw / ar); else dw \= (int) (dh \* ar); break; case SURFACE\_4\_3:
        ar \= 4.0 / 3.0; if (dar < ar)
            dh \= (int) (dw / ar); else dw \= (int) (dh \* ar); break; case SURFACE\_ORIGINAL:
        dh \= mVideoHeight;
        dw \= mVideoWidth; break;
    }

    mSurfaceHolder.setFixedSize(mVideoWidth, mVideoHeight);
    ViewGroup.LayoutParams lp \= mSurfaceView.getLayoutParams();
    lp.width \= dw;
    lp.height \= dh;
    mSurfaceView.setLayoutParams(lp);
    mSurfaceView.invalidate();
}

}

复制代码

    代码说明 

      1、vlc-android的版本为2.2.0-pre1 Weatherwax

      2、拷贝vlc-android官网例子下面org.videolan.libvlc所有的类,以及VLCInstance、Preferences。只有声音没有画面就出在VLCInstance这个问题上,少了一些配置,参考VLCInstance.updateLibVlcSettings。

      3、playMRL不要用Uri来转,否则打不开

      4、提供的代码已经编译好了so,也修改源码打开了EventHandler.MediaPlayerBuffering(也修改了libvlcjni.c),但是还是没有缓冲进度的值,还有待进一步探索。

      5、实际发现如果只在surfaceChanged中attachSurface,setSurfaceSize回调不会触发,需要同时在surfaceCreated中设置。

      6、本文不讨论Handler非静态可能引发内存泄露的问题,大家写的时候自己注意一下 :) 

  下载

    https://github.com/over140/vlc-android-demo (注意工程是Android Studio的工程)

  文章

    1、vlc-android 中调用用libvlcjni.so实现流媒体播放 

    2、[Github]vlc-android-macbuild

    3、vlc android的编译及截图,录制视频等功能

    4、vlc-android源码编译过程记录

    5、vlc-android 获取MediaPlayerEncounteredError,MediaPlayerBuffering等各种事件的响应

    6、Vlc-for-android源码分析

结束

   文章2的GitHub项目是对vlc进行封装,也挺不错了,值得参考。vlc-android的例子写的比较复杂,而且api可能老变,大家看文章的时候注意一下版本问题。