一个视频文件通常有一个视频轨,多个音频轨,多个字幕轨;
多个音频轨 国语音轨,英语音轨,粤语音轨之类的
多个字幕轨 英语字幕轨 中文字幕轨 日文字幕轨之类的
播放视频的时候可以切换音频轨和切换字幕轨
LibVLC类主要负责控制音频和视频的播放暂停等,还负责音频轨和字幕轨的切换
播放视频是在surfaceview上进行的,可以设置媒体列表后进行上一首,下一首
MediaDatabase类主要负责视频播放保存和获取视频信息(播放时间),还有
保存和获取搜索到的音频列表和视频列表
MediaLibrary类就是负责查找设备上音频和视频列表,返回视频列表和音频列表
EventHandler也是一个很重要的类,是一个单例模式的,用户如果需要监听LibVLC播放音视频
的状态,就调用addHandler(Handler)方法进行注册,EventHandler里面有一个callback函数,
他是由LibVLCnative层调用通知用户状态发生变化
这个Handler里面处理的消息有
public static final int MediaParsedChanged = 3;
//public static final int MediaFreed = 4;
//public static final int MediaStateChanged = 5;
//public static final int MediaPlayerMediaChanged = 0x100;
//public static final int MediaPlayerNothingSpecial = 0x101;
//public static final int MediaPlayerOpening = 0x102;
//public static final int MediaPlayerBuffering = 0x103;
public static final int MediaPlayerPlaying = 0x104;
public static final int MediaPlayerPaused = 0x105;
public static final int MediaPlayerStopped = 0x106;
//public static final int MediaPlayerForward = 0x107;
//public static final int MediaPlayerBackward = 0x108;
public static final int MediaPlayerEndReached = 0x109;
public static final int MediaPlayerEncounteredError = 0x10a;
接收到消息后的处理
@Override
public void handleMessage(Message msg) {
VideoPlayerActivity activity = getOwner();
if(activity == null) return;
// Do not handle events if we are leaving the VideoPlayerActivity
if (activity.mSwitchingView) return;
switch (msg.getData().getInt("event")) {
case EventHandler.MediaParsedChanged:
Log.i(TAG, "MediaParsedChanged");
if (activity.mLibVLC.getVideoTracksCount() < 1) {
Log.i(TAG, "No video track, open in audio mode");
activity.switchToAudioMode();
}
break;
case EventHandler.MediaPlayerPlaying:
Log.i(TAG, "MediaPlayerPlaying");
activity.stopLoadingAnimation();
activity.showOverlay();
/** FIXME: update the track list when it changes during the
* playback. (#7540) */
activity.setESTrackLists(true);
activity.setESTracks();
activity.changeAudioFocus(true);
break;
case EventHandler.MediaPlayerPaused:
Log.i(TAG, "MediaPlayerPaused");
break;
case EventHandler.MediaPlayerStopped:
Log.i(TAG, "MediaPlayerStopped");
activity.changeAudioFocus(false);
break;
case EventHandler.MediaPlayerEndReached:
Log.i(TAG, "MediaPlayerEndReached");
activity.changeAudioFocus(false);
activity.endReached();
break;
case EventHandler.MediaPlayerVout:
activity.handleVout(msg);
break;
case EventHandler.MediaPlayerPositionChanged:
if (!activity.mCanSeek)
activity.mCanSeek = true;
//don't spam the logs
break;
case EventHandler.MediaPlayerEncounteredError:
Log.i(TAG, "MediaPlayerEncounteredError");
activity.encounteredError();
break;
case EventHandler.HardwareAccelerationError:
Log.i(TAG, "HardwareAccelerationError");
activity.handleHardwareAccelerationError();
break;
default:
Log.e(TAG, String.format("Event not handled (0x%x)", msg.getData().getInt("event")));
break;
}
播放视频的时候需要实现IVideoPlayer接口 处理设置surface的大小