diff --git a/Libraries/LibMedia/Containers/Matroska/MatroskaDemuxer.cpp b/Libraries/LibMedia/Containers/Matroska/MatroskaDemuxer.cpp index e510fa118e..f7f69dd620 100644 --- a/Libraries/LibMedia/Containers/Matroska/MatroskaDemuxer.cpp +++ b/Libraries/LibMedia/Containers/Matroska/MatroskaDemuxer.cpp @@ -68,6 +68,8 @@ static TrackType track_type_from_matroska_track_type(TrackEntry::TrackType type) static Track track_from_track_entry(TrackEntry const& track_entry) { + // FIXME: Set the kind correctly. + auto kind = Track::Kind::None; auto name = Utf16String::from_utf8(track_entry.name()); auto language = [&] { // LanguageBCP47 - The language of the track, in the BCP47 form; see basics on language codes. If this Element is used, @@ -76,7 +78,7 @@ static Track track_from_track_entry(TrackEntry const& track_entry) return Utf16String::from_utf8(track_entry.language_bcp_47().value()); return Utf16String::from_utf8(track_entry.language()); }(); - Track track(track_type_from_matroska_track_type(track_entry.track_type()), track_entry.track_number(), name, language); + Track track(track_type_from_matroska_track_type(track_entry.track_type()), track_entry.track_number(), kind, name, language); if (track.type() == TrackType::Video) { auto video_track = track_entry.video_track(); diff --git a/Libraries/LibMedia/FFmpeg/FFmpegDemuxer.cpp b/Libraries/LibMedia/FFmpeg/FFmpegDemuxer.cpp index 81f71b62c4..588db16043 100644 --- a/Libraries/LibMedia/FFmpeg/FFmpegDemuxer.cpp +++ b/Libraries/LibMedia/FFmpeg/FFmpegDemuxer.cpp @@ -57,9 +57,11 @@ static DecoderErrorOr create_track_from_stream(AVStream const& stream) return Utf16String(); return Utf16String::from_utf8(StringView(name_entry->value, strlen(name_entry->value))); }; + // FIXME: Set the kind correctly. + auto kind = Track::Kind::None; auto name = get_string_metadata("title"); auto language = get_string_metadata("language"); - Track track(type, stream.index, name, language); + Track track(type, stream.index, kind, name, language); if (type == TrackType::Video) { auto color_primaries = static_cast(stream.codecpar->color_primaries); diff --git a/Libraries/LibMedia/Track.h b/Libraries/LibMedia/Track.h index bbc4d0dacd..a7a389488b 100644 --- a/Libraries/LibMedia/Track.h +++ b/Libraries/LibMedia/Track.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include #include @@ -19,6 +20,7 @@ namespace Media { class Track { +public: struct VideoData { u64 pixel_width { 0 }; u64 pixel_height { 0 }; @@ -29,11 +31,27 @@ class Track { Audio::SampleSpecification sample_specification; }; -public: - Track(TrackType type, size_t identifier, Utf16String const& name, Utf16String const& language) + // Derived from the "kind" attributes in: + // https://dev.w3.org/html5/html-sourcing-inband-tracks/ + enum class Kind : u8 { + None, + Alternative, + Captions, + Descriptions, + Main, + MainDesc, + Metadata, + Sign, + Subtitles, + Translation, + Commentary, + }; + + Track(TrackType type, size_t identifier, Kind kind, Utf16String const& label, Utf16String const& language) : m_type(type) , m_identifier(identifier) - , m_name(name) + , m_kind(kind) + , m_label(label) , m_language(language) { switch (m_type) { @@ -51,7 +69,8 @@ public: TrackType type() const { return m_type; } size_t identifier() const { return m_identifier; } - Utf16String const& name() const { return m_name; } + Kind kind() const { return m_kind; } + Utf16String const& label() const { return m_label; } Utf16String const& language() const { return m_language; } void set_video_data(VideoData data) @@ -91,12 +110,42 @@ public: private: TrackType m_type { 0 }; size_t m_identifier { 0 }; - Utf16String m_name; + Kind m_kind { Kind::None }; + Utf16String m_label; Utf16String m_language; Variant m_track_data; }; +constexpr Utf16View track_kind_to_string(Track::Kind kind) +{ + switch (kind) { + case Track::Kind::None: + return u""sv; + case Track::Kind::Alternative: + return u"alternative"sv; + case Track::Kind::Captions: + return u"captions"sv; + case Track::Kind::Descriptions: + return u"descriptions"sv; + case Track::Kind::Main: + return u"main"sv; + case Track::Kind::MainDesc: + return u"maindesc"sv; + case Track::Kind::Metadata: + return u"metadata"sv; + case Track::Kind::Sign: + return u"sign"sv; + case Track::Kind::Subtitles: + return u"subtitles"sv; + case Track::Kind::Translation: + return u"translation"sv; + case Track::Kind::Commentary: + return u"commentary"sv; + } + VERIFY_NOT_REACHED(); +} + } template<> diff --git a/Libraries/LibWeb/HTML/HTMLMediaElement.cpp b/Libraries/LibWeb/HTML/HTMLMediaElement.cpp index 13ac7b3034..b8677cdee3 100644 --- a/Libraries/LibWeb/HTML/HTMLMediaElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLMediaElement.cpp @@ -1377,18 +1377,6 @@ void HTMLMediaElement::on_audio_track_added(Media::Track const& track) if (enable == TriState::True) audio_track->set_enabled(true); - // NB: According to https://dev.w3.org/html5/html-sourcing-inband-tracks/, kind should be set according to format, and the following criteria within - // the specified formats. - // WebM: - // - "main": the FlagDefault element is set on the track - // - "translation": not first audio (video) track - // MP4: - // - "main": first audio (video) track - // - "translation": not first audio (video) track - // Though the behavior for WebM is not clear if its first track is not marked with FlagDefault, the idea here seems to be that the preferred - // track should be marked as "main", and the rest should be marked as "translation". - audio_track->set_kind(enable == TriState::True ? "main"_utf16 : "translation"_utf16); - // 7. Fire an event named addtrack at this AudioTrackList object, using TrackEvent, with the track attribute initialized to the new AudioTrack object. TrackEventInit event_init {}; event_init.track = GC::make_root(audio_track); @@ -1432,9 +1420,6 @@ void HTMLMediaElement::on_video_track_added(Media::Track const& track) if (enable == TriState::True) video_track->set_selected(true); - // NB: See the comment regarding AudioTrack.kind above with regard to https://dev.w3.org/html5/html-sourcing-inband-tracks/. - video_track->set_kind(enable == TriState::True ? "main"_utf16 : "translation"_utf16); - // 7. Fire an event named addtrack at this VideoTrackList object, using TrackEvent, with the track attribute initialized to the new VideoTrack object. TrackEventInit event_init {}; event_init.track = GC::make_root(video_track); diff --git a/Libraries/LibWeb/HTML/MediaTrackBase.cpp b/Libraries/LibWeb/HTML/MediaTrackBase.cpp index 0aa0d983df..9d3eb926ba 100644 --- a/Libraries/LibWeb/HTML/MediaTrackBase.cpp +++ b/Libraries/LibWeb/HTML/MediaTrackBase.cpp @@ -15,7 +15,8 @@ MediaTrackBase::MediaTrackBase(JS::Realm& realm, GC::Ref media , m_media_element(media_element) , m_track_in_playback_manager(track) , m_id(Utf16String::number(track.identifier())) - , m_label(track.name()) + , m_kind(track.kind()) + , m_label(track.label()) { // https://html.spec.whatwg.org/multipage/media.html#dom-audiotrack-language // https://html.spec.whatwg.org/multipage/media.html#dom-videotrack-language diff --git a/Libraries/LibWeb/HTML/MediaTrackBase.h b/Libraries/LibWeb/HTML/MediaTrackBase.h index c7d4c860b9..fd15997fec 100644 --- a/Libraries/LibWeb/HTML/MediaTrackBase.h +++ b/Libraries/LibWeb/HTML/MediaTrackBase.h @@ -22,8 +22,8 @@ public: Media::Track const& track_in_playback_manager() const { return m_track_in_playback_manager; } Utf16String const& id() const { return m_id; } - Utf16String const& kind() const { return m_kind; } - void set_kind(Utf16String const& kind) { m_kind = kind; } + Utf16View kind() const { return Media::track_kind_to_string(m_kind); } + void set_kind(Media::Track::Kind kind) { m_kind = kind; } Utf16String const& label() const { return m_label; } Utf16String const& language() const { return m_language; } @@ -43,7 +43,7 @@ private: // https://html.spec.whatwg.org/multipage/media.html#dom-audiotrack-kind // https://html.spec.whatwg.org/multipage/media.html#dom-videotrack-kind - Utf16String m_kind; + Media::Track::Kind m_kind; // https://html.spec.whatwg.org/multipage/media.html#dom-audiotrack-label // https://html.spec.whatwg.org/multipage/media.html#dom-videotrack-label