Skip to content

Commit 5456072

Browse files
Zaggy1024gmta
authored andcommitted
LibWeb: Implement audio media data processing through PlaybackManager
1 parent dfe59b8 commit 5456072

File tree

5 files changed

+74
-72
lines changed

5 files changed

+74
-72
lines changed

Libraries/LibWeb/HTML/AudioTrack.cpp

Lines changed: 3 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
#include <AK/IDAllocator.h>
88
#include <LibJS/Runtime/Realm.h>
99
#include <LibJS/Runtime/VM.h>
10-
#include <LibMedia/Audio/Loader.h>
1110
#include <LibWeb/Bindings/AudioTrackPrototype.h>
1211
#include <LibWeb/Bindings/Intrinsics.h>
1312
#include <LibWeb/DOM/Event.h>
@@ -16,33 +15,18 @@
1615
#include <LibWeb/HTML/EventNames.h>
1716
#include <LibWeb/HTML/HTMLMediaElement.h>
1817
#include <LibWeb/Layout/Node.h>
19-
#include <LibWeb/Painting/Paintable.h>
20-
#include <LibWeb/Platform/AudioCodecPlugin.h>
2118

2219
namespace Web::HTML {
2320

2421
GC_DEFINE_ALLOCATOR(AudioTrack);
2522

2623
static IDAllocator s_audio_track_id_allocator;
2724

28-
AudioTrack::AudioTrack(JS::Realm& realm, GC::Ref<HTMLMediaElement> media_element, NonnullRefPtr<Audio::Loader> loader)
25+
AudioTrack::AudioTrack(JS::Realm& realm, GC::Ref<HTMLMediaElement> media_element, Media::Track const& track)
2926
: PlatformObject(realm)
3027
, m_media_element(media_element)
31-
, m_audio_plugin(Platform::AudioCodecPlugin::create(move(loader)).release_value_but_fixme_should_propagate_errors())
28+
, m_track_in_playback_manager(track)
3229
{
33-
m_audio_plugin->on_playback_position_updated = [this](auto position) {
34-
if (auto* paintable = m_media_element->paintable())
35-
paintable->set_needs_display();
36-
37-
auto playback_position = static_cast<double>(position.to_milliseconds()) / 1000.0;
38-
m_media_element->set_current_playback_position(playback_position);
39-
};
40-
41-
m_audio_plugin->on_decoder_error = [this](String error_message) {
42-
m_media_element->set_decoder_error(move(error_message));
43-
};
44-
45-
update_volume();
4630
}
4731

4832
AudioTrack::~AudioTrack()
@@ -62,34 +46,6 @@ void AudioTrack::initialize(JS::Realm& realm)
6246
m_id = String::number(id);
6347
}
6448

65-
void AudioTrack::play()
66-
{
67-
m_audio_plugin->resume_playback();
68-
}
69-
70-
void AudioTrack::pause()
71-
{
72-
m_audio_plugin->pause_playback();
73-
}
74-
75-
AK::Duration AudioTrack::duration()
76-
{
77-
return m_audio_plugin->duration();
78-
}
79-
80-
void AudioTrack::seek(double position, MediaSeekMode seek_mode)
81-
{
82-
// FIXME: Implement seeking mode.
83-
(void)seek_mode;
84-
85-
m_audio_plugin->seek(position);
86-
}
87-
88-
void AudioTrack::update_volume()
89-
{
90-
m_audio_plugin->set_volume(m_media_element->effective_media_volume());
91-
}
92-
9349
void AudioTrack::visit_edges(Cell::Visitor& visitor)
9450
{
9551
Base::visit_edges(visitor);
@@ -116,6 +72,7 @@ void AudioTrack::set_enabled(bool enabled)
11672
}
11773

11874
m_enabled = enabled;
75+
m_media_element->set_audio_track_enabled({}, this, enabled);
11976
}
12077

12178
}

Libraries/LibWeb/HTML/AudioTrack.h

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@
77
#pragma once
88

99
#include <AK/String.h>
10-
#include <AK/Time.h>
1110
#include <LibMedia/Audio/Forward.h>
11+
#include <LibMedia/Track.h>
1212
#include <LibWeb/Bindings/PlatformObject.h>
1313

1414
namespace Web::HTML {
@@ -22,14 +22,6 @@ class AudioTrack final : public Bindings::PlatformObject {
2222

2323
void set_audio_track_list(Badge<AudioTrackList>, GC::Ptr<AudioTrackList> audio_track_list) { m_audio_track_list = audio_track_list; }
2424

25-
void play();
26-
void pause();
27-
28-
AK::Duration duration();
29-
void seek(double, MediaSeekMode);
30-
31-
void update_volume();
32-
3325
String const& id() const { return m_id; }
3426
String const& kind() const { return m_kind; }
3527
String const& label() const { return m_label; }
@@ -38,8 +30,10 @@ class AudioTrack final : public Bindings::PlatformObject {
3830
bool enabled() const { return m_enabled; }
3931
void set_enabled(bool enabled);
4032

33+
Media::Track const& track_in_playback_manager() const { return m_track_in_playback_manager; }
34+
4135
private:
42-
AudioTrack(JS::Realm&, GC::Ref<HTMLMediaElement>, NonnullRefPtr<Audio::Loader>);
36+
AudioTrack(JS::Realm&, GC::Ref<HTMLMediaElement>, Media::Track const&);
4337

4438
virtual void initialize(JS::Realm&) override;
4539
virtual void visit_edges(Cell::Visitor&) override;
@@ -62,7 +56,7 @@ class AudioTrack final : public Bindings::PlatformObject {
6256
GC::Ref<HTMLMediaElement> m_media_element;
6357
GC::Ptr<AudioTrackList> m_audio_track_list;
6458

65-
NonnullOwnPtr<Platform::AudioCodecPlugin> m_audio_plugin;
59+
Media::Track m_track_in_playback_manager;
6660
};
6761

6862
}

Libraries/LibWeb/HTML/AudioTrackList.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,12 @@ class AudioTrackList final : public DOM::EventTarget {
2929
bool has_enabled_track() const;
3030

3131
template<typename Callback>
32-
void for_each_enabled_track(Callback&& callback)
32+
void for_each_track(Callback&& callback)
3333
{
3434
for (auto& audio_track : m_audio_tracks) {
35-
if (audio_track->enabled())
36-
callback(*audio_track);
35+
auto iteration_decision = callback(*audio_track);
36+
if (iteration_decision == IterationDecision::Break)
37+
break;
3738
}
3839
}
3940

Libraries/LibWeb/HTML/HTMLMediaElement.cpp

Lines changed: 60 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,6 +1126,14 @@ bool HTMLMediaElement::verify_response(GC::Ref<Fetch::Infrastructure::Response>
11261126
TODO();
11271127
}
11281128

1129+
void HTMLMediaElement::set_audio_track_enabled(Badge<AudioTrack>, GC::Ptr<HTML::AudioTrack> audio_track, bool enabled)
1130+
{
1131+
if (enabled)
1132+
m_playback_manager->enable_an_audio_track(audio_track->track_in_playback_manager());
1133+
else
1134+
m_playback_manager->disable_an_audio_track(audio_track->track_in_playback_manager());
1135+
}
1136+
11291137
void HTMLMediaElement::set_selected_video_track(Badge<VideoTrack>, GC::Ptr<HTML::VideoTrack> video_track)
11301138
{
11311139
set_needs_style_update(true);
@@ -1194,17 +1202,51 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::process_media_data(Function<void(Str
11941202

11951203
m_playback_manager = playback_manager_result.release_value();
11961204

1197-
// FIXME: -> If the media resource is found to have an audio track
1198-
// 1. Create an AudioTrack object to represent the audio track.
1199-
// 2. Update the media element's audioTracks attribute's AudioTrackList object with the new AudioTrack object.
1200-
// 3. Let enable be unknown.
1201-
// 4. If either the media resource or the URL of the current media resource indicate a particular set of audio tracks to enable, or if
1202-
// the user agent has information that would facilitate the selection of specific audio tracks to improve the user's experience, then:
1203-
// if this audio track is one of the ones to enable, then set enable to true, otherwise, set enable to false.
1204-
// 5. If enable is still unknown, then, if the media element does not yet have an enabled audio track, then set enable to true, otherwise,
1205-
// set enable to false.
1206-
// 6. If enable is true, then enable this audio track, otherwise, do not enable this audio track.
1207-
// 7. Fire an event named addtrack at this AudioTrackList object, using TrackEvent, with the track attribute initialized to the new AudioTrack object.
1205+
// -> If the media resource is found to have an audio track
1206+
auto preferred_audio_track = m_playback_manager->preferred_audio_track();
1207+
auto has_enabled_preferred_audio_track = false;
1208+
1209+
for (auto const& track : m_playback_manager->audio_tracks()) {
1210+
// 1. Create an AudioTrack object to represent the audio track.
1211+
auto audio_track = realm.create<AudioTrack>(realm, *this, track);
1212+
1213+
// 2. Update the media element's audioTracks attribute's AudioTrackList object with the new AudioTrack object.
1214+
m_audio_tracks->add_track({}, audio_track);
1215+
1216+
// 3. Let enable be unknown.
1217+
auto enable = TriState::Unknown;
1218+
1219+
// 4. If either the media resource or the URL of the current media resource indicate a particular set of audio tracks to enable, or if
1220+
// the user agent has information that would facilitate the selection of specific audio tracks to improve the user's experience, then:
1221+
// if this audio track is one of the ones to enable, then set enable to true, otherwise, set enable to false.
1222+
if (preferred_audio_track.has_value()) {
1223+
if (track == preferred_audio_track && !has_enabled_preferred_audio_track) {
1224+
enable = TriState::True;
1225+
has_enabled_preferred_audio_track = true;
1226+
} else {
1227+
enable = TriState::False;
1228+
}
1229+
}
1230+
1231+
// 5. If enable is still unknown, then, if the media element does not yet have an enabled audio track, then set enable to true, otherwise,
1232+
// set enable to false.
1233+
if (enable == TriState::Unknown)
1234+
enable = !m_audio_tracks->has_enabled_track() ? TriState::True : TriState::False;
1235+
1236+
// 6. If enable is true, then enable this audio track, otherwise, do not enable this audio track.
1237+
if (enable == TriState::True)
1238+
audio_track->set_enabled(true);
1239+
1240+
// 7. Fire an event named addtrack at this AudioTrackList object, using TrackEvent, with the track attribute initialized to the new AudioTrack object.
1241+
TrackEventInit event_init {};
1242+
event_init.track = GC::make_root(audio_track);
1243+
1244+
auto event = TrackEvent::create(realm, HTML::EventNames::addtrack, move(event_init));
1245+
m_audio_tracks->dispatch_event(event);
1246+
}
1247+
1248+
if (preferred_audio_track.has_value())
1249+
VERIFY(has_enabled_preferred_audio_track);
12081250

12091251
// -> If the media resource is found to have a video track
12101252
auto preferred_video_track = m_playback_manager->preferred_video_track();
@@ -1301,7 +1343,13 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::process_media_data(Function<void(Str
13011343
// FIXME: 11. If either the media resource or the URL of the current media resource indicate a particular start time, then set the initial playback
13021344
// position to that time and, if jumped is still false, seek to that time.
13031345

1304-
// FIXME: 12. If there is no enabled audio track, then enable an audio track. This will cause a change event to be fired.
1346+
// 12. If there is no enabled audio track, then enable an audio track. This will cause a change event to be fired.
1347+
if (!m_audio_tracks->has_enabled_track()) {
1348+
m_audio_tracks->for_each_track([](auto& track) {
1349+
track.set_enabled(true);
1350+
return IterationDecision::Break;
1351+
});
1352+
}
13051353

13061354
// 13. If there is no selected video track, then select a video track. This will cause a change event to be fired.
13071355
if (m_video_tracks->selected_index() == -1) {

Libraries/LibWeb/HTML/HTMLMediaElement.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ class HTMLMediaElement : public HTMLElement {
130130
GC::Ref<VideoTrackList> video_tracks() const { return *m_video_tracks; }
131131
GC::Ref<TextTrackList> text_tracks() const { return *m_text_tracks; }
132132

133+
void set_audio_track_enabled(Badge<AudioTrack>, GC::Ptr<HTML::AudioTrack> audio_track, bool);
134+
133135
void set_selected_video_track(Badge<VideoTrack>, GC::Ptr<HTML::VideoTrack> video_track);
134136

135137
void update_video_frame_and_timeline();

0 commit comments

Comments
 (0)