From 090ebb253b1a0c390d1cfc20242f3220a7b4e1a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=AE=87=E8=88=AA?= <2546789017@qq.com> Date: Tue, 22 Aug 2017 12:08:47 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=AB=A0=E8=8A=82=E8=B7=B3?= =?UTF-8?q?=E8=BD=AC=E7=9A=84=E6=A7=BD=E5=87=BD=E6=95=B0=EF=BC=8C=E5=B7=B2?= =?UTF-8?q?=E5=88=9D=E6=AD=A5=E6=B5=8B=E8=AF=95=E9=80=9A=E8=BF=87=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/AVPlayer.cpp | 62 ++++++++++++++++++++++++++++++++++++++++++++- src/QtAV/AVPlayer.h | 8 +++++- 2 files changed, 68 insertions(+), 2 deletions(-) diff --git a/src/AVPlayer.cpp b/src/AVPlayer.cpp index 95fc4c854..e7a96d073 100644 --- a/src/AVPlayer.cpp +++ b/src/AVPlayer.cpp @@ -1,4 +1,4 @@ -/****************************************************************************** +/****************************************************************************** QtAV: Multimedia framework based on Qt and FFmpeg Copyright (C) 2012-2017 Wang Bin @@ -45,6 +45,9 @@ #include "QtAV/private/AVCompat.h" #include "utils/internal.h" #include "utils/Logger.h" +extern "C" { +#include +} #define EOF_ISSUE_SOLVED 0 namespace QtAV { @@ -680,6 +683,7 @@ void AVPlayer::loadInternal() d->video_tracks = d->getTracksInfo(&d->demuxer, AVDemuxer::VideoStream); Q_EMIT internalVideoTracksChanged(d->video_tracks); Q_EMIT durationChanged(duration()); + Q_EMIT chaptersChanged(chapters()); // setup parameters from loaded media d->media_start_pts = d->demuxer.startTime(); // TODO: what about other proctols? some vob duration() == 0 @@ -715,6 +719,7 @@ void AVPlayer::unload() d->vdec = 0; } d->demuxer.unload(); + Q_EMIT chaptersChanged(0); Q_EMIT durationChanged(0LL); // for ui, slider is invalid. use stopped instead, and remove this signal here? // ?? d->audio_tracks = d->getTracksInfo(&d->demuxer, AVDemuxer::AudioStream); @@ -1385,6 +1390,42 @@ void AVPlayer::tryClearVideoRenderers() } } +void AVPlayer::seekChapter(int incr) +{ + if (!chapters()) + return; + + qint64 pos = masterClock()->value() * AV_TIME_BASE; + int i = 0; + + AVFormatContext *ic = d->demuxer.formatContext(); + + AVRational av_time_base_q; + av_time_base_q.num = 1; + av_time_base_q.den = AV_TIME_BASE; + + /* find the current chapter */ + for (i = 0; i < chapters(); ++i) { + AVChapter *ch = ic->chapters[i]; + if (av_compare_ts(pos, av_time_base_q, ch->start, ch->time_base) < 0) { + --i; + break; + } + } + + i += incr; + //i = FFMAX(i, 0); + if (i <= 0) + i = 0; + if (i >= chapters()) + return; + + //av_log(NULL, AV_LOG_VERBOSE, "Seeking to chapter %d.\n", i); + qDebug() << QString::fromLatin1("Seeking to chapter : ") << QString::number(i); + setPosition(av_rescale_q(ic->chapters[i]->start, ic->chapters[i]->time_base, + av_time_base_q) / 1000); +} + void AVPlayer::stop() { // check d->timer_id, <0 return? @@ -1532,6 +1573,20 @@ void AVPlayer::seekBackward() seek(position() - kSeekMS); } +void AVPlayer::seekNextChapter() +{ + if (chapters() <= 1) + return; + seekChapter(1); +} + +void AVPlayer::seekPreviousChapter() +{ + if (chapters() <= 1) + return; + seekChapter(-1); +} + void AVPlayer::setSeekType(SeekType type) { d->seek_type = type; @@ -1635,6 +1690,11 @@ int AVPlayer::saturation() const return d->saturation; } +unsigned int AVPlayer::chapters() const +{ + return d->demuxer.formatContext()->nb_chapters; +} + void AVPlayer::setSaturation(int val) { if (d->saturation == val) diff --git a/src/QtAV/AVPlayer.h b/src/QtAV/AVPlayer.h index eed9e2651..0f0d57085 100644 --- a/src/QtAV/AVPlayer.h +++ b/src/QtAV/AVPlayer.h @@ -1,4 +1,4 @@ -/****************************************************************************** +/****************************************************************************** QtAV: Multimedia framework based on Qt and FFmpeg Copyright (C) 2012-2017 Wang Bin @@ -82,6 +82,7 @@ class Q_AV_EXPORT AVPlayer : public QObject Q_PROPERTY(State state READ state WRITE setState NOTIFY stateChanged) Q_PROPERTY(QtAV::MediaStatus mediaStatus READ mediaStatus NOTIFY mediaStatusChanged) Q_PROPERTY(QtAV::MediaEndAction mediaEndAction READ mediaEndAction WRITE setMediaEndAction NOTIFY mediaEndActionChanged) + Q_PROPERTY(qint64 chapters READ chapters NOTIFY chaptersChanged) Q_ENUMS(State) public: /*! @@ -374,6 +375,7 @@ class Q_AV_EXPORT AVPlayer : public QObject int contrast() const; int hue() const; //not implemented int saturation() const; + unsigned int chapters() const; /*! * \sa AVDemuxer::setOptions() * example: @@ -489,6 +491,8 @@ public Q_SLOTS: void seek(qint64 pos); //ms. same as setPosition(pos) void seekForward(); void seekBackward(); + void seekNextChapter(); + void seekPreviousChapter(); void setSeekType(SeekType type); SeekType seekType() const; @@ -579,6 +583,7 @@ public Q_SLOTS: void contrastChanged(int val); void hueChanged(int val); void saturationChanged(int val); + void chaptersChanged(unsigned int val); void subtitleStreamChanged(int value); /*! * \brief internalAudioTracksChanged @@ -611,6 +616,7 @@ private Q_SLOTS: void updateMediaStatus(QtAV::MediaStatus status); void onSeekFinished(qint64 value); void tryClearVideoRenderers(); + void seekChapter(int incr); protected: // TODO: set position check timer interval virtual void timerEvent(QTimerEvent *);