对于使用第三方的sdk库做开发,除了基本的操作函数接口外,还希望通过事件机制拿到消息通知,比如当前播放进度、音量值变化、静音变化、文件长度、播放结束等,有了这些才是完整的播放功能,在vlc中要拿到各种事件需要先通过libvlc_event_attach订阅事件,不需要的时候用libvlc_event_detach取消订阅即可,函数中第二个参数指定是何种事件类型,常用的事件类型有下列:
void VlcHelper::attachEvents(libvlc_event_manager_t *vlcEvent, VlcThread *thread)
{libvlc_event_attach(vlcEvent, libvlc_MediaPlayerLengthChanged, handleEvents, thread);libvlc_event_attach(vlcEvent, libvlc_MediaPlayerTimeChanged, handleEvents, thread);libvlc_event_attach(vlcEvent, libvlc_MediaPlayerAudioVolume, handleEvents, thread);libvlc_event_attach(vlcEvent, libvlc_MediaPlayerMuted, handleEvents, thread);libvlc_event_attach(vlcEvent, libvlc_MediaPlayerUnmuted, handleEvents, thread);libvlc_event_attach(vlcEvent, libvlc_MediaPlayerSnapshotTaken, handleEvents, thread);//libvlc_event_attach(vlcEvent, libvlc_MediaPlayerPositionChanged, handleEvents, thread);//libvlc_event_attach(vlcEvent, libvlc_MediaParsedChanged, handleEvents, thread);//libvlc_event_attach(vlcEvent, libvlc_MediaPlayerOpening, handleEvents, thread);//libvlc_event_attach(vlcEvent, libvlc_MediaPlayerPlaying, handleEvents, thread);//libvlc_event_attach(vlcEvent, libvlc_MediaPlayerPaused, handleEvents, thread);//libvlc_event_attach(vlcEvent, libvlc_MediaPlayerStopped, handleEvents, thread);libvlc_event_attach(vlcEvent, libvlc_MediaPlayerEndReached, handleEvents, thread);libvlc_event_attach(vlcEvent, libvlc_MediaPlayerEncounteredError, handleEvents, thread);libvlc_event_attach(vlcEvent, libvlc_MediaPlayerVout, handleEvents, thread);
}void VlcHelper::detachEvents(libvlc_event_manager_t *vlcEvent, VlcThread *thread)
{libvlc_event_detach(vlcEvent, libvlc_MediaPlayerLengthChanged, handleEvents, thread);libvlc_event_detach(vlcEvent, libvlc_MediaPlayerTimeChanged, handleEvents, thread);libvlc_event_detach(vlcEvent, libvlc_MediaPlayerAudioVolume, handleEvents, thread);libvlc_event_detach(vlcEvent, libvlc_MediaPlayerMuted, handleEvents, thread);libvlc_event_detach(vlcEvent, libvlc_MediaPlayerUnmuted, handleEvents, thread);libvlc_event_detach(vlcEvent, libvlc_MediaPlayerSnapshotTaken, handleEvents, thread);//libvlc_event_detach(vlcEvent, libvlc_MediaPlayerPositionChanged, handleEvents, thread);//libvlc_event_detach(vlcEvent, libvlc_MediaParsedChanged, handleEvents, thread);//libvlc_event_detach(vlcEvent, libvlc_MediaPlayerOpening, handleEvents, thread);//libvlc_event_detach(vlcEvent, libvlc_MediaPlayerPlaying, handleEvents, thread);//libvlc_event_detach(vlcEvent, libvlc_MediaPlayerPaused, handleEvents, thread);//libvlc_event_detach(vlcEvent, libvlc_MediaPlayerStopped, handleEvents, thread);libvlc_event_detach(vlcEvent, libvlc_MediaPlayerEndReached, handleEvents, thread);libvlc_event_detach(vlcEvent, libvlc_MediaPlayerEncounteredError, handleEvents, thread);libvlc_event_detach(vlcEvent, libvlc_MediaPlayerVout, handleEvents, thread);
}void VlcHelper::handleEvents(const libvlc_event_t *event, void *data)
{VlcThread *thread = (VlcThread *)data;//在回调事件中更新最后的消息时间thread->updateTime();//qDebug() << TIMEMS << event->type;switch (event->type) {case libvlc_MediaPlayerLengthChanged: {qint64 duration = event->u.media_player_length_changed.new_length;if (duration > 0 && thread->getIsFile()) {QMetaObject::invokeMethod(thread, "receiveDuration", Q_ARG(qint64, duration));}}break;case libvlc_MediaPlayerTimeChanged: {qint64 position = event->u.media_player_time_changed.new_time;if (position > 0 && thread->getIsFile()) {QMetaObject::invokeMethod(thread, "receivePosition", Q_ARG(qint64, position));//如果设置了重复循环播放则快到了文件末尾重新设置位置即可if (thread->getPlayRepeat() && (thread->getDuration() - position) < 500) {QMetaObject::invokeMethod(thread, "setPosition", Q_ARG(qint64, 0));}}}break;case libvlc_MediaPlayerAudioVolume: {//这里获取到的音量值是 0.1 - 1.0float volume = event->u.media_player_audio_volume.volume * 100;QMetaObject::invokeMethod(thread, "receiveVolume", Q_ARG(int, volume));}break;case libvlc_MediaPlayerMuted: {bool muted = true;QMetaObject::invokeMethod(thread, "receiveMuted", Q_ARG(bool, muted));}break;case libvlc_MediaPlayerUnmuted: {bool muted = false;QMetaObject::invokeMethod(thread, "receiveMuted", Q_ARG(bool, muted));}break;case libvlc_MediaPlayerSnapshotTaken: {QMetaObject::invokeMethod(thread, "snapFinsh");}break;case libvlc_MediaPlayerPositionChanged: {float position = event->u.media_player_position_changed.new_position;thread->debug("播放进度", QString("进度: %1").arg(position));}break;case libvlc_MediaParsedChanged:thread->debug("媒体信息", "");break;case libvlc_MediaPlayerOpening:thread->debug("播放结束", "");break;case libvlc_MediaPlayerPlaying:thread->debug("播放开始", "");break;case libvlc_MediaPlayerPaused:thread->debug("播放暂停", "");break;case libvlc_MediaPlayerStopped:thread->debug("播放停止", "");break;case libvlc_MediaPlayerEndReached: {thread->debug("播放结束", "");thread->stop2();}break;case libvlc_MediaPlayerEncounteredError: {thread->debug("发生错误", "");thread->stop2();}break;case libvlc_MediaPlayerVout: {//识别尺寸发生变化thread->checkVideoSize();}break;default:break;}
}