由于libmpv中的time-pos属性记录的是当前分片的播放进度,如果我们使用mpv播放m3u8格式文件(有多个视频分片)就会导致time-pos记录的时间并不是整个视频播放的总时间,所以想要通过time-pos来显示当前视频的播放进度是行不通的。我的解决办法是:
-
先读取m3u8文件中的内容,获取总视频分片的个数、每个视频分片的时长、在整个视频中的索引、在整个视频的起止时间
class VideoSegmentInfo{ public: int _index; //片段在整个视频中的索引 double _duration; //持续时长 QString _url; //地址 //当前分片在整段视频中的位置 double _startPos; double _endPos; }; -
使用libmpv中的方法获取当前播放视频的分片索引,以及当前分片的播放位置(也就是
time-pos)cppmpv_get_property(_mpv, "playlist-pos", MPV_FORMAT_INT64, &_curSegmentIndex); mpv_get_property(_mpv, "time-pos", MPV_FORMAT_DOUBLE, &_curSegmentPlayDuration); -
做一个很简单的相加就可以得到当前视频播放的总进度
cppif(_curSegmentIndex == 0){ _curPlayTime = (int64_t)_curSegmentPlayDuration; }else{ _curPlayTime = (int64_t)(_curSegmentPlayDuration + (*_segmentInfoList)[_curSegmentIndex-1]._endPos); } -
还有一个问题:设置拖拽进度条的时间,由于传递的进度条时间也是视频播放的总时间,所以我们需要转化一下,定位到具体分配以及该分片下的播放进度,此时又有一个问题:
如果我们使用mpv_set_property来设置
playlist-pos和time-pos,例如:cppfor(int i = 0; i < _curSegmentIndex; ++i) { if(seconds >= (*_segmentInfoList)[i]._startPos && seconds <= (*_segmentInfoList)[i]._endPos) { //如果处于第i个视频分片,跳转到此视频分片 mpv_set_property_async(_mpv, 0, "playlist-pos", MPV_FORMAT_INT64, &i); int64_t pos = (int64_t)(seconds - (*_segmentInfoList)[i]._startPos); mpv_set_property_async(_mpv, 0, "time-pos", MPV_FORMAT_INT64, &pos); _curSegmentIndex = i; _curSegmentPlayDuration = pos; } }由于这个方法是异步的,所以这两个参数的设置顺序可能会错乱,导致设置异常,因此应该使用命令链来设置参数:
cppQString cmd = QString("set playlist-pos %1; set time-pos %2").arg(i).arg(pos); mpv_command_string(_mpv, cmd.toUtf8().constData());