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()); }
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 }