Example #1
0
void MediaControls::disableShowingTextTracks() {
  TextTrackList* trackList = mediaElement().textTracks();
  for (unsigned i = 0; i < trackList->length(); ++i) {
    TextTrack* track = trackList->anonymousIndexedGetter(i);
    if (track->mode() == TextTrack::showingKeyword())
      track->setMode(TextTrack::disabledKeyword());
  }
}
void AutomaticTrackSelection::perform(TextTrackList& textTracks)
{
    TrackGroup captionAndSubtitleTracks(TrackGroup::CaptionsAndSubtitles);
    TrackGroup descriptionTracks(TrackGroup::Description);
    TrackGroup chapterTracks(TrackGroup::Chapter);
    TrackGroup metadataTracks(TrackGroup::Metadata);

    for (size_t i = 0; i < textTracks.length(); ++i) {
        TextTrack* textTrack = textTracks.item(i);
        if (!textTrack)
            continue;

        String kind = textTrack->kind();
        TrackGroup* currentGroup;
        if (kind == TextTrack::subtitlesKeyword() || kind == TextTrack::captionsKeyword()) {
            currentGroup = &captionAndSubtitleTracks;
        } else if (kind == TextTrack::descriptionsKeyword()) {
            currentGroup = &descriptionTracks;
        } else if (kind == TextTrack::chaptersKeyword()) {
            currentGroup = &chapterTracks;
        } else {
            ASSERT(kind == TextTrack::metadataKeyword());
            currentGroup = &metadataTracks;
        }

        if (!currentGroup->visibleTrack && textTrack->mode() == TextTrack::showingKeyword())
            currentGroup->visibleTrack = textTrack;
        if (!currentGroup->defaultTrack && textTrack->isDefault())
            currentGroup->defaultTrack = textTrack;

        // Do not add this track to the group if it has already been automatically configured
        // as we only want to perform selection once per track so that adding another track
        // after the initial configuration doesn't reconfigure every track - only those that
        // should be changed by the new addition. For example all metadata tracks are
        // disabled by default, and we don't want a track that has been enabled by script
        // to be disabled automatically when a new metadata track is added later.
        if (textTrack->hasBeenConfigured())
            continue;

        if (textTrack->language().length())
            currentGroup->hasSrcLang = true;
        currentGroup->tracks.append(textTrack);
    }

    if (captionAndSubtitleTracks.tracks.size())
        performAutomaticTextTrackSelection(captionAndSubtitleTracks);
    if (descriptionTracks.tracks.size())
        performAutomaticTextTrackSelection(descriptionTracks);
    if (chapterTracks.tracks.size())
        performAutomaticTextTrackSelection(chapterTracks);
    if (metadataTracks.tracks.size())
        enableDefaultMetadataTextTracks(metadataTracks);
}
Example #3
0
void MediaControlClosedCaptionsTrackListElement::updateDisplay()
{
#if ENABLE(VIDEO_TRACK)
    DEFINE_STATIC_LOCAL(AtomicString, selectedClassValue, ("selected", AtomicString::ConstructFromLiteral));

    if (!mediaController()->hasClosedCaptions())
        return;

    HTMLMediaElement* mediaElement = toParentMediaElement(this);
    if (!mediaElement)
        return;

    TextTrackList* trackList = mediaElement->textTracks();

    if (!trackList || !trackList->length())
        return;

    if (m_trackListHasChanged)
        rebuildTrackListMenu();

    bool captionsVisible = mediaElement->closedCaptionsVisible();
    for (unsigned i = 0, length = m_menuItems.size(); i < length; ++i) {
        RefPtr<Element> trackItem = m_menuItems[i];
        int trackIndex = trackListIndexForElement(trackItem.get());
        if (trackIndex != HTMLMediaElement::textTracksIndexNotFound()) {
            if (trackIndex == HTMLMediaElement::textTracksOffIndex()) {
                if (captionsVisible)
                    trackItem->classList()->remove(selectedClassValue, ASSERT_NO_EXCEPTION);
                else
                    trackItem->classList()->add(selectedClassValue, ASSERT_NO_EXCEPTION);
            } else {
                TextTrack* track = trackList->item(trackIndex);
                if (!track)
                    continue;
                if (track->mode() == TextTrack::showingKeyword())
                    trackItem->classList()->add(selectedClassValue, ASSERT_NO_EXCEPTION);
                else
                    trackItem->classList()->remove(selectedClassValue, ASSERT_NO_EXCEPTION);
            }
        }
    }
#endif
}
Example #4
0
void MediaSource::removeSourceBuffer(SourceBuffer& buffer, ExceptionCode& ec)
{
    LOG(MediaSource, "MediaSource::removeSourceBuffer() %p", this);
    Ref<SourceBuffer> protect(buffer);

    // 2. If sourceBuffer specifies an object that is not in sourceBuffers then
    // throw a NOT_FOUND_ERR exception and abort these steps.
    if (!m_sourceBuffers->length() || !m_sourceBuffers->contains(buffer)) {
        ec = NOT_FOUND_ERR;
        return;
    }

    // 3. If the sourceBuffer.updating attribute equals true, then run the following steps: ...
    buffer.abortIfUpdating();

    // 4. Let SourceBuffer audioTracks list equal the AudioTrackList object returned by sourceBuffer.audioTracks.
    RefPtr<AudioTrackList> audioTracks = buffer.audioTracks();

    // 5. If the SourceBuffer audioTracks list is not empty, then run the following steps:
    if (audioTracks->length()) {
        // 5.1 Let HTMLMediaElement audioTracks list equal the AudioTrackList object returned by the audioTracks
        // attribute on the HTMLMediaElement.
        // 5.2 Let the removed enabled audio track flag equal false.
        bool removedEnabledAudioTrack = false;

        // 5.3 For each AudioTrack object in the SourceBuffer audioTracks list, run the following steps:
        while (audioTracks->length()) {
            AudioTrack* track = audioTracks->lastItem();

            // 5.3.1 Set the sourceBuffer attribute on the AudioTrack object to null.
            track->setSourceBuffer(nullptr);

            // 5.3.2 If the enabled attribute on the AudioTrack object is true, then set the removed enabled
            // audio track flag to true.
            if (track->enabled())
                removedEnabledAudioTrack = true;

            // 5.3.3 Remove the AudioTrack object from the HTMLMediaElement audioTracks list.
            // 5.3.4 Queue a task to fire a trusted event named removetrack, that does not bubble and is not
            // cancelable, and that uses the TrackEvent interface, at the HTMLMediaElement audioTracks list.
            if (mediaElement())
                mediaElement()->removeAudioTrack(track);

            // 5.3.5 Remove the AudioTrack object from the SourceBuffer audioTracks list.
            // 5.3.6 Queue a task to fire a trusted event named removetrack, that does not bubble and is not
            // cancelable, and that uses the TrackEvent interface, at the SourceBuffer audioTracks list.
            audioTracks->remove(track);
        }

        // 5.4 If the removed enabled audio track flag equals true, then queue a task to fire a simple event
        // named change at the HTMLMediaElement audioTracks list.
        if (removedEnabledAudioTrack)
            mediaElement()->audioTracks()->scheduleChangeEvent();
    }

    // 6. Let SourceBuffer videoTracks list equal the VideoTrackList object returned by sourceBuffer.videoTracks.
    RefPtr<VideoTrackList> videoTracks = buffer.videoTracks();

    // 7. If the SourceBuffer videoTracks list is not empty, then run the following steps:
    if (videoTracks->length()) {
        // 7.1 Let HTMLMediaElement videoTracks list equal the VideoTrackList object returned by the videoTracks
        // attribute on the HTMLMediaElement.
        // 7.2 Let the removed selected video track flag equal false.
        bool removedSelectedVideoTrack = false;

        // 7.3 For each VideoTrack object in the SourceBuffer videoTracks list, run the following steps:
        while (videoTracks->length()) {
            VideoTrack* track = videoTracks->lastItem();

            // 7.3.1 Set the sourceBuffer attribute on the VideoTrack object to null.
            track->setSourceBuffer(nullptr);

            // 7.3.2 If the selected attribute on the VideoTrack object is true, then set the removed selected
            // video track flag to true.
            if (track->selected())
                removedSelectedVideoTrack = true;

            // 7.3.3 Remove the VideoTrack object from the HTMLMediaElement videoTracks list.
            // 7.3.4 Queue a task to fire a trusted event named removetrack, that does not bubble and is not
            // cancelable, and that uses the TrackEvent interface, at the HTMLMediaElement videoTracks list.
            if (mediaElement())
                mediaElement()->removeVideoTrack(track);

            // 7.3.5 Remove the VideoTrack object from the SourceBuffer videoTracks list.
            // 7.3.6 Queue a task to fire a trusted event named removetrack, that does not bubble and is not
            // cancelable, and that uses the TrackEvent interface, at the SourceBuffer videoTracks list.
            videoTracks->remove(track);
        }

        // 7.4 If the removed selected video track flag equals true, then queue a task to fire a simple event
        // named change at the HTMLMediaElement videoTracks list.
        if (removedSelectedVideoTrack)
            mediaElement()->videoTracks()->scheduleChangeEvent();
    }

    // 8. Let SourceBuffer textTracks list equal the TextTrackList object returned by sourceBuffer.textTracks.
    RefPtr<TextTrackList> textTracks = buffer.textTracks();

    // 9. If the SourceBuffer textTracks list is not empty, then run the following steps:
    if (textTracks->length()) {
        // 9.1 Let HTMLMediaElement textTracks list equal the TextTrackList object returned by the textTracks
        // attribute on the HTMLMediaElement.
        // 9.2 Let the removed enabled text track flag equal false.
        bool removedEnabledTextTrack = false;

        // 9.3 For each TextTrack object in the SourceBuffer textTracks list, run the following steps:
        while (textTracks->length()) {
            TextTrack* track = textTracks->lastItem();

            // 9.3.1 Set the sourceBuffer attribute on the TextTrack object to null.
            track->setSourceBuffer(nullptr);

            // 9.3.2 If the mode attribute on the TextTrack object is set to "showing" or "hidden", then
            // set the removed enabled text track flag to true.
            if (track->mode() == TextTrack::showingKeyword() || track->mode() == TextTrack::hiddenKeyword())
                removedEnabledTextTrack = true;

            // 9.3.3 Remove the TextTrack object from the HTMLMediaElement textTracks list.
            // 9.3.4 Queue a task to fire a trusted event named removetrack, that does not bubble and is not
            // cancelable, and that uses the TrackEvent interface, at the HTMLMediaElement textTracks list.
            if (mediaElement())
                mediaElement()->removeTextTrack(track);

            // 9.3.5 Remove the TextTrack object from the SourceBuffer textTracks list.
            // 9.3.6 Queue a task to fire a trusted event named removetrack, that does not bubble and is not
            // cancelable, and that uses the TrackEvent interface, at the SourceBuffer textTracks list.
            textTracks->remove(track);
        }
        
        // 9.4 If the removed enabled text track flag equals true, then queue a task to fire a simple event
        // named change at the HTMLMediaElement textTracks list.
        if (removedEnabledTextTrack)
            mediaElement()->textTracks()->scheduleChangeEvent();
    }
    
    
    // 10. If sourceBuffer is in activeSourceBuffers, then remove sourceBuffer from activeSourceBuffers ...
    m_activeSourceBuffers->remove(buffer);
    
    // 11. Remove sourceBuffer from sourceBuffers and fire a removesourcebuffer event
    // on that object.
    m_sourceBuffers->remove(buffer);
    
    // 12. Destroy all resources for sourceBuffer.
    buffer.removedFromMediaSource();
}
void AutomaticTrackSelection::performAutomaticTextTrackSelection(const TrackGroup& group)
{
    ASSERT(group.tracks.size());

    // First, find the track in the group that should be enabled (if any).
    HeapVector<Member<TextTrack>> currentlyEnabledTracks;
    TextTrack* trackToEnable = nullptr;
    TextTrack* defaultTrack = nullptr;
    TextTrack* preferredTrack = nullptr;
    TextTrack* fallbackTrack = nullptr;
    int highestTrackScore = 0;

    for (size_t i = 0; i < group.tracks.size(); ++i) {
        TextTrack* textTrack = group.tracks[i];

        if (m_configuration.disableCurrentlyEnabledTracks && textTrack->mode() == TextTrack::showingKeyword())
            currentlyEnabledTracks.append(textTrack);

        int trackScore = textTrackSelectionScore(*textTrack);

        if (textTrack->kind() == preferredTrackKind())
            trackScore += 1;
        if (trackScore) {
            // * If the text track kind is subtitles or captions and the user has indicated an interest in having a
            // track with this text track kind, text track language, and text track label enabled, and there is no
            // other text track in the media element's list of text tracks with a text track kind of either subtitles
            // or captions whose text track mode is showing
            //    Let the text track mode be showing.
            if (trackScore > highestTrackScore) {
                preferredTrack = textTrack;
                highestTrackScore = trackScore;
            }
            if (!defaultTrack && textTrack->isDefault())
                defaultTrack = textTrack;

            if (!fallbackTrack)
                fallbackTrack = textTrack;
        } else if (!group.visibleTrack && !defaultTrack && textTrack->isDefault()) {
            // * If the track element has a default attribute specified, and there is no other text track in the media
            // element's list of text tracks whose text track mode is showing or showing by default
            //    Let the text track mode be showing by default.
            defaultTrack = textTrack;
        }
    }

    if (m_configuration.textTrackKindUserPreference != TextTrackKindUserPreference::Default)
        trackToEnable = preferredTrack;

    if (!trackToEnable && defaultTrack)
        trackToEnable = defaultTrack;

    if (!trackToEnable && m_configuration.forceEnableSubtitleOrCaptionTrack && group.kind == TrackGroup::CaptionsAndSubtitles) {
        if (fallbackTrack)
            trackToEnable = fallbackTrack;
        else
            trackToEnable = group.tracks[0];
    }

    if (currentlyEnabledTracks.size()) {
        for (size_t i = 0; i < currentlyEnabledTracks.size(); ++i) {
            TextTrack* textTrack = currentlyEnabledTracks[i];
            if (textTrack != trackToEnable)
                textTrack->setMode(TextTrack::disabledKeyword());
        }
    }

    if (trackToEnable)
        trackToEnable->setMode(TextTrack::showingKeyword());
}
static v8::Handle<v8::Value> modeAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
{
    TextTrack* imp = V8TextTrack::toNative(info.Holder());
    return v8String(imp->mode(), info.GetIsolate());
}