Repository: LadybirdBrowser/ladybird
File: Libraries/LibWeb/HTML/HTMLMediaElement.cpp (C++)

Code before:
        } else {
            weak_self->on_video_track_added(track);
        }
    };

    // -> Once enough of the media data has been fetched to determine the duration of the media resource, its dimensions, and other metadata
    m_playback_manager->on_metadata_parsed = [weak_self = GC::Weak(*this)] {
        if (!weak_self)
            return;
        weak_self->on_metadata_parsed();
    };

    // -> If the media data can be fetched but is found by inspection to be in an unsupported format, or can otherwise not be rendered at all
    m_playback_manager->on_unsupported_format_error = [weak_self = GC::Weak(*this), fetch_data](auto&& error) mutable {
        if (!weak_self)
            return;

        // 1. The user agent should cancel the fetching process.
        weak_self->cancel_the_fetching_process();

        // 2. Abort this subalgorithm, returning to the resource selection algorithm.
        fetch_data->failure_callback(MUST(String::from_utf8(error.description())));
    };

    // -> If the media data is corrupted
    m_playback_manager->on_error = [weak_self = GC::Weak(*this)](Media::DecoderError&& error) {
        if (!weak_self)
            return;
        weak_self->set_decoder_error(MUST(String::from_utf8(error.description())));
    };

    m_playback_manager->add_media_source(*fetch_data->stream);

    m_playback_manager->on_playback_state_change = [weak_self = GC::Weak(*this)] {
        if (weak_self)
            weak_self->on_playback_manager_state_change();
    };
}

// https://html.spec.whatwg.org/multipage/media.html#media-data-processing-steps-list
void HTMLMediaElement::process_media_data(FetchingStatus fetching_status)
{
    // -> Once the entire media resource has been fetched (but potentially before any of it has been decoded)
    if (fetching_status == FetchingStatus::Complete) {
        // Fire an event named progress at the media element.
        dispatch_event(DOM::Event::create(this->realm(), HTML::EventNames::progress));

        // Set the networkState to NETWORK_IDLE and fire an event named suspend at the media element.
        m_network_state = NetworkState::Idle;
        dispatch_event(DOM::Event::create(this->realm(), HTML::EventNames::suspend));
    }

Review comment (suggestion):
This was just merged, but we have `weak_callback` for this now. There are some example usages in this file already.

Code after:

    // -> If the media resource is found to have an audio track
    // -> If the media resource is found to have a video track
    m_playback_manager->on_track_added = GC::weak_callback(*this, [](auto& self, auto track_type, auto& track) {
        if (track_type == Media::TrackType::Audio)
            self.on_audio_track_added(track);
        else
            self.on_video_track_added(track);
    });

    // -> Once enough of the media data has been fetched to determine the duration of the media resource, its dimensions, and other metadata
    m_playback_manager->on_metadata_parsed = GC::weak_callback(*this, [](auto& self) {
        self.on_metadata_parsed();
    });

    // -> If the media data can be fetched but is found by inspection to be in an unsupported format, or can otherwise not be rendered at all
    m_playback_manager->on_unsupported_format_error = GC::weak_callback(*this, [fetch_data = fetch_data](auto& self, Media::DecoderError&& error) mutable {
        // NB: Queue a task for this so that we don't destroy the PlaybackManager within one of its callbacks when we
        //     call forget_media_resource_specific_tracks().
        self.queue_a_media_element_task([self = GC::Weak(self), fetch_data = fetch_data, error = move(error)] {
            if (!self)
                return;
            if (self->m_error)
                return;

            // 1. The user agent should cancel the fetching process.
            self->cancel_the_fetching_process();

            // 2. Abort this subalgorithm, returning to the resource selection algorithm.
            fetch_data->failure_callback(MUST(String::from_utf8(error.description())));
        });
    });

    // -> If the media data is corrupted
    m_playback_manager->on_error = GC::weak_callback(*this, [](auto& self, Media::DecoderError&& error) {
        self.set_decoder_error(MUST(String::from_utf8(error.description())));
    });

    m_playback_manager->add_media_source(*fetch_data->stream);

    m_playback_manager->on_playback_state_change = GC::weak_callback(*this, [](auto& self) {
        self.on_playback_manager_state_change();
    });
}

// https://html.spec.whatwg.org/multipage/media.html#media-data-processing-steps-list
void HTMLMediaElement::process_media_data(FetchingStatus fetching_status)
{
    auto& realm = this->realm();

    // -> Once the entire media resource has been fetched (but potentially before any of it has been decoded)