您的位置:首页 > 移动开发 > Android开发

【VLC-Android】vlc-android简例

2016-03-18 00:00 585 查看
摘要: 【VLC-Android】vlc-android简例

前言

  继续折腾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可能老变,大家看文章的时候注意一下版本问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: