Пример #1
0
void MediaSource::setDurationInternal(const MediaTime& duration)
{
    // Duration Change Algorithm
    // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#duration-change-algorithm

    // 1. If the current value of duration is equal to new duration, then return.
    if (duration == m_duration)
        return;

    // 2. Set old duration to the current value of duration.
    MediaTime oldDuration = m_duration;

    // 3. Update duration to new duration.
    m_duration = duration;

    // 4. If the new duration is less than old duration, then call remove(new duration, old duration)
    // on all objects in sourceBuffers.
    if (oldDuration.isValid() && duration < oldDuration) {
        for (auto& sourceBuffer : *m_sourceBuffers)
            sourceBuffer->rangeRemoval(duration, oldDuration);
    }

    // 5. If a user agent is unable to partially render audio frames or text cues that start before and end after the
    // duration, then run the following steps:
    // 5.1 Update new duration to the highest end time reported by the buffered attribute across all SourceBuffer objects
    // in sourceBuffers.
    // 5.2 Update duration to new duration.
    // NOTE: Assume UA is able to partially render audio frames.

    // 6. Update the media controller duration to new duration and run the HTMLMediaElement duration change algorithm.
    LOG(MediaSource, "MediaSource::setDurationInternal(%p) - duration(%g)", this, duration.toDouble());
    m_private->durationChanged();
}
Пример #2
0
void MediaSource::seekToTime(const MediaTime& time)
{
    // 2.4.3 Seeking
    // https://dvcs.w3.org/hg/html-media/raw-file/tip/media-source/media-source.html#mediasource-seeking

    m_pendingSeekTime = time;

    LOG(MediaSource, "MediaSource::seekToTime(%p, %f): %lu active source buffers", this, time.toDouble(), m_activeSourceBuffers->length());
    // Run the following steps as part of the "Wait until the user agent has established whether or not the
    // media data for the new playback position is available, and, if it is, until it has decoded enough data
    // to play back that position" step of the seek algorithm:
    // 1. The media element looks for media segments containing the new playback position in each SourceBuffer
    // object in activeSourceBuffers.
    for (auto& sourceBuffer : *m_activeSourceBuffers) {
        // ↳ If one or more of the objects in activeSourceBuffers is missing media segments for the new
        // playback position
        if (!sourceBuffer->buffered()->ranges().contain(time)) {
            // 1.1 Set the HTMLMediaElement.readyState attribute to HAVE_METADATA.
            m_private->setReadyState(MediaPlayer::HaveMetadata);

            // 1.2 The media element waits until an appendBuffer() or an appendStream() call causes the coded
            // frame processing algorithm to set the HTMLMediaElement.readyState attribute to a value greater
            // than HAVE_METADATA.
            LOG(MediaSource, "MediaSource::seekToTime(%p) - waitForSeekCompleted()", this);
            m_private->waitForSeekCompleted();
            return;
        } else
            LOG(MediaSource, "MediaSource::seekToTime(%p) - seek time buffered already.", this);
        // ↳ Otherwise
        // Continue
    }

    completeSeek();
}