AVFoundation: store seek requests before media is loaded.

And actually seek once the media is loaded.

Task-number: QTBUG-48057
Change-Id: I9446a1e66a48f9a94c039be9af81689ed04bc56c
Reviewed-by: Christian Stromme <christian.stromme@theqtcompany.com>
This commit is contained in:
Yoann Lopes
2015-09-03 18:33:17 +02:00
parent 6a6a69b7d8
commit bede0a838d
2 changed files with 27 additions and 5 deletions

View File

@@ -166,6 +166,7 @@ private:
bool m_tryingAsync; bool m_tryingAsync;
int m_volume; int m_volume;
qreal m_rate; qreal m_rate;
qint64 m_requestedPosition;
qint64 m_duration; qint64 m_duration;
bool m_videoAvailable; bool m_videoAvailable;

View File

@@ -391,6 +391,7 @@ AVFMediaPlayerSession::AVFMediaPlayerSession(AVFMediaPlayerService *service, QOb
, m_tryingAsync(false) , m_tryingAsync(false)
, m_volume(100) , m_volume(100)
, m_rate(1.0) , m_rate(1.0)
, m_requestedPosition(-1)
, m_duration(0) , m_duration(0)
, m_videoAvailable(false) , m_videoAvailable(false)
, m_audioAvailable(false) , m_audioAvailable(false)
@@ -468,6 +469,8 @@ void AVFMediaPlayerSession::setMedia(const QMediaContent &content, QIODevice *st
setAudioAvailable(false); setAudioAvailable(false);
setVideoAvailable(false); setVideoAvailable(false);
m_requestedPosition = -1;
Q_EMIT positionChanged(position());
QMediaPlayer::MediaStatus oldMediaStatus = m_mediaStatus; QMediaPlayer::MediaStatus oldMediaStatus = m_mediaStatus;
@@ -479,7 +482,6 @@ void AVFMediaPlayerSession::setMedia(const QMediaContent &content, QIODevice *st
if (m_mediaStatus != oldMediaStatus) if (m_mediaStatus != oldMediaStatus)
Q_EMIT mediaStatusChanged(m_mediaStatus); Q_EMIT mediaStatusChanged(m_mediaStatus);
Q_EMIT positionChanged(position());
return; return;
} else { } else {
@@ -487,6 +489,7 @@ void AVFMediaPlayerSession::setMedia(const QMediaContent &content, QIODevice *st
if (m_mediaStatus != oldMediaStatus) if (m_mediaStatus != oldMediaStatus)
Q_EMIT mediaStatusChanged(m_mediaStatus); Q_EMIT mediaStatusChanged(m_mediaStatus);
} }
//Load AVURLAsset //Load AVURLAsset
//initialize asset using content's URL //initialize asset using content's URL
NSString *urlString = [NSString stringWithUTF8String:content.canonicalUrl().toEncoded().constData()]; NSString *urlString = [NSString stringWithUTF8String:content.canonicalUrl().toEncoded().constData()];
@@ -499,7 +502,7 @@ qint64 AVFMediaPlayerSession::position() const
AVPlayerItem *playerItem = [(AVFMediaPlayerSessionObserver*)m_observer playerItem]; AVPlayerItem *playerItem = [(AVFMediaPlayerSessionObserver*)m_observer playerItem];
if (!playerItem) if (!playerItem)
return 0; return m_requestedPosition != -1 ? m_requestedPosition : 0;
CMTime time = [playerItem currentTime]; CMTime time = [playerItem currentTime];
return static_cast<quint64>(float(time.value) / float(time.timescale) * 1000.0f); return static_cast<quint64>(float(time.value) / float(time.timescale) * 1000.0f);
@@ -619,14 +622,23 @@ void AVFMediaPlayerSession::setPosition(qint64 pos)
qDebug() << Q_FUNC_INFO << pos; qDebug() << Q_FUNC_INFO << pos;
#endif #endif
if ( !isSeekable() || pos == position()) if (pos == position())
return; return;
AVPlayerItem *playerItem = [(AVFMediaPlayerSessionObserver*)m_observer playerItem]; AVPlayerItem *playerItem = [(AVFMediaPlayerSessionObserver*)m_observer playerItem];
if (!playerItem) {
if (!playerItem) m_requestedPosition = pos;
Q_EMIT positionChanged(m_requestedPosition);
return; return;
} else if (!isSeekable()) {
if (m_requestedPosition != -1) {
m_requestedPosition = -1;
Q_EMIT positionChanged(position());
}
return;
}
pos = qMax(qint64(0), pos);
if (duration() > 0) if (duration() > 0)
pos = qMin(pos, duration()); pos = qMin(pos, duration());
@@ -823,6 +835,11 @@ void AVFMediaPlayerSession::processLoadStateChange()
if (m_duration != currentDuration) if (m_duration != currentDuration)
Q_EMIT durationChanged(m_duration = currentDuration); Q_EMIT durationChanged(m_duration = currentDuration);
if (m_requestedPosition != -1) {
setPosition(m_requestedPosition);
m_requestedPosition = -1;
}
newStatus = isPlaying ? QMediaPlayer::BufferedMedia : QMediaPlayer::LoadedMedia; newStatus = isPlaying ? QMediaPlayer::BufferedMedia : QMediaPlayer::LoadedMedia;
if (m_state == QMediaPlayer::PlayingState && [(AVFMediaPlayerSessionObserver*)m_observer player]) { if (m_state == QMediaPlayer::PlayingState && [(AVFMediaPlayerSessionObserver*)m_observer player]) {
@@ -842,6 +859,10 @@ void AVFMediaPlayerSession::processPositionChange()
void AVFMediaPlayerSession::processMediaLoadError() void AVFMediaPlayerSession::processMediaLoadError()
{ {
if (m_requestedPosition != -1) {
m_requestedPosition = -1;
Q_EMIT positionChanged(position());
}
Q_EMIT error(QMediaPlayer::FormatError, tr("Failed to load media")); Q_EMIT error(QMediaPlayer::FormatError, tr("Failed to load media"));
Q_EMIT mediaStatusChanged(m_mediaStatus = QMediaPlayer::InvalidMedia); Q_EMIT mediaStatusChanged(m_mediaStatus = QMediaPlayer::InvalidMedia);
Q_EMIT stateChanged(m_state = QMediaPlayer::StoppedState); Q_EMIT stateChanged(m_state = QMediaPlayer::StoppedState);