static int textTrackLanguageSelectionScore(const TextTrack& track)
{
    if (track.language().isEmpty())
        return 0;

    Vector<AtomicString> languages = userPreferredLanguages();
    size_t languageMatchIndex = indexOfBestMatchingLanguageInList(track.language(), languages);
    if (languageMatchIndex >= languages.size())
        return 0;

    return languages.size() - languageMatchIndex;
}
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);
}
static v8::Handle<v8::Value> languageAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info)
{
    TextTrack* imp = V8TextTrack::toNative(info.Holder());
    return v8String(imp->language(), info.GetIsolate());
}
Example #4
0
void MediaControlClosedCaptionsTrackListElement::rebuildTrackListMenu()
{
#if ENABLE(VIDEO_TRACK)
    // Remove any existing content.
    removeChildren();
    m_menuItems.clear();

    m_trackListHasChanged = false;

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

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

    TextTrackList* trackList = mediaElement->textTracks();

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

    Document* doc = document();

    RefPtr<Element> captionsSection = doc->createElement(sectionTag, ASSERT_NO_EXCEPTION);
    RefPtr<Element> captionsHeader = doc->createElement(h3Tag, ASSERT_NO_EXCEPTION);
    captionsHeader->appendChild(doc->createTextNode(textTrackClosedCaptionsText()));
    captionsSection->appendChild(captionsHeader);
    RefPtr<Element> captionsMenuList = doc->createElement(ulTag, ASSERT_NO_EXCEPTION);

    RefPtr<Element> subtitlesSection = doc->createElement(sectionTag, ASSERT_NO_EXCEPTION);
    RefPtr<Element> subtitlesHeader = doc->createElement(h3Tag, ASSERT_NO_EXCEPTION);
    subtitlesHeader->appendChild(doc->createTextNode(textTrackSubtitlesText()));
    subtitlesSection->appendChild(subtitlesHeader);
    RefPtr<Element> subtitlesMenuList = doc->createElement(ulTag, ASSERT_NO_EXCEPTION);

    RefPtr<Element> trackItem;

    trackItem = doc->createElement(liTag, ASSERT_NO_EXCEPTION);
    trackItem->appendChild(doc->createTextNode(textTrackOffText()));
    trackItem->setAttribute(trackIndexAttributeName(), textTracksOffAttrValue, ASSERT_NO_EXCEPTION);
    captionsMenuList->appendChild(trackItem);
    m_menuItems.append(trackItem);

    trackItem = doc->createElement(liTag, ASSERT_NO_EXCEPTION);
    trackItem->appendChild(doc->createTextNode(textTrackOffText()));
    trackItem->setAttribute(trackIndexAttributeName(), textTracksOffAttrValue, ASSERT_NO_EXCEPTION);
    subtitlesMenuList->appendChild(trackItem);
    m_menuItems.append(trackItem);

    bool hasCaptions = false;
    bool hasSubtitles = false;

    for (unsigned i = 0, length = trackList->length(); i < length; ++i) {
        TextTrack* track = trackList->item(i);
        trackItem = doc->createElement(liTag, ASSERT_NO_EXCEPTION);

        // Add a custom attribute to the <li> element which will allow
        // us to easily associate the user tapping here with the
        // track. Since this list is rebuilt if the tracks change, we
        // should always be in sync.
        trackItem->setAttribute(trackIndexAttributeName(), String::number(i), ASSERT_NO_EXCEPTION);

        AtomicString labelText = track->label();
        if (labelText.isNull() || labelText.isEmpty())
            labelText = displayNameForLanguageLocale(track->language());
        if (labelText.isNull() || labelText.isEmpty())
            labelText = textTrackNoLabelText();
        trackItem->appendChild(doc->createTextNode(labelText));

        if (track->kind() == track->captionsKeyword()) {
            hasCaptions = true;
            insertTextTrackMenuItemIntoSortedContainer(trackItem, captionsMenuList);
        }
        if (track->kind() == track->subtitlesKeyword()) {
            hasSubtitles = true;
            insertTextTrackMenuItemIntoSortedContainer(trackItem, subtitlesMenuList);
        }
        m_menuItems.append(trackItem);
    }

    captionsSection->appendChild(captionsMenuList);
    subtitlesSection->appendChild(subtitlesMenuList);

    if (hasCaptions)
        appendChild(captionsSection);
    if (hasSubtitles)
        appendChild(subtitlesSection);

    updateDisplay();
#endif
}