Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Icecast and Shoutcast metadata detect [Android] #384

Closed
wants to merge 5 commits into from
Closed

Icecast and Shoutcast metadata detect [Android] #384

wants to merge 5 commits into from

Conversation

xgustavoh
Copy link

@xgustavoh xgustavoh commented Jan 5, 2019

Closed / Discontinued.

Replaced with #552 (Best Performance).

Metadata detection was implemented, using the code created by @saschpe (android-exoplayer2-ext-icy or ExoPlayer), where it performs HTTP detection for ExoPlayer.

The icy-update event that is called when the meta-date is updated.

this._updateIcyMetaData = TrackPlayer.addEventListener("icy-update", (data) => {
    console.log("icy-update", data);
})

Two attributes are sent in this event:

  • streamTitle: Matches the song title and artist currently playing in streaming.
  • streamUrl: Contains more information that is sent to Icecast in the format as a link, this information is defined in the software used for the transmission. (In Shoutcast servers this option is not possible to change).

The icy-header event was disregarded for this implementation because it was taken into account that it is not "necessary" to use the same event.

The type ICY audio was added because the operation with the HLS is possible, but through the @saschpe code the same does not work, because in HLS the sending of the metadata is not at the beginning of the data received obligatorily.

To update the notification, it is recommended to use the code implemented by @HybridFox (#331). Because the direct updating of the information would not be a good thing, because the person can obtain information from the metadata and make a query in an api and with the result obtained to update the notification.

In the application I'm developing. The cover code of the song is sent in streamUrl, so I make a query in my API.

If you want to test, you can use this Track for testing:

{
    "type": "icy",
    "id": "1111",
    "url": "https://live.hunter.fm/pop2k",
    "title": "Hunter.FM",
    "artist": "The POP2k Channel",
    "artwork": "https://cdn.hunter.fm/image/thumb/station/pop2k-first/300x300ht.jpg"
}

Note: Sorry for the previous code, the same was done after getting many problems with other "players" being so was doing during a time of fatigue.

Note²: If you want to implement the icy-header I can do it.


public IcyMetadataListener onIcyMetadaUpdate(){
return manager.onIcyMetadaUpdate();
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally unnecessary method here, you can call the MusicManager directly instead of going through the player

Copy link
Author

@xgustavoh xgustavoh Jan 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I read the code, I ended up reading wrong and noticed that the MusicManager manager in ExoPlayback.java was set to private. But reading again I noticed that it is defined as protected, so the LocalPlayback class has access to it.

To 'delete' this function, I will have to change the scope of toMediaSource.

From:

public MediaSource toMediaSource (Context ctx, LocalPlayback playback) {
    ...
}

To:

public MediaSource toMediaSource (Context ctx, LocalPlayback playback, MusicManager manager) {
    ...
}

Changing also the LocalPlayBack.java file on lines 73 and 83 to:

Linha 73:

source.addMediaSource(index, track.toMediaSource(context, this, manager), Utils.toRunnable(promise));

Linha 83:

trackList.add(track.toMediaSource(context, this, manager));

@Guichaguri
Copy link
Collaborator

Thanks, that's a huge improvement! There are still a few things not quite right, but I'll help you with those tomorrow.

What I mean is that you can use the same event for both the metadata and the header, I'll show you tomorrow how that should work.

@xgustavoh
Copy link
Author

Thanks, that's a huge improvement! There are still a few things not quite right, but I'll help you with those tomorrow.

What I mean is that you can use the same event for both the metadata and the header, I'll show you tomorrow how that should work.

I totally agree with you, the code is actually cleaner and readable.

About Header, I understood perfectly how to use the same event for both types.

It would basically add a bundle.putString ("type", "metadata"); or bundle.putString ("type", "header"); according to the event in which it is being submitted. That's what I actually imagined.

@@ -59,6 +60,16 @@ public void onReceive(Context context, Intent intent) {

private boolean stopWithApp = false;

private IcyMetadataListener icyMetadaUpdate = new IcyMetadataListener() {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should straight up crash if you didn't enabled the icy extension.

@Guichaguri
Copy link
Collaborator

Guichaguri commented Jan 7, 2019

Here are the major changes I did:

  • Moved the metadata listener to a new class, that way it will not crash if you don't have the library present at runtime.
    • The way the JVM works is that it will only check if a class/method/field exists once it is initialized. In your code, you were initializing it without checking if the icy extension was available or not.
    • It was creating unused memory, as the listener would only be used after an icy track was added.
  • Started using RN's OkHttp singleton, which allows the icy stream to share the custom options put into that.
  • Renamed the event to playback-metadata-received
    • The name is not final yet, maybe it's too long
    • The idea is to use the same event for other types of metadata (such as ID3)
  • Added a metadata object to the event, containing the raw data (just in case you have custom stuff there)
  • Readded the icy-headers

I didn't tested this yet.

Due to this being a pretty specific feature, this might be moved to an "addon module" in the future, we'll see how it goes.

We should look into saschpe/android-exoplayer2-ext-icy#2 before merging this.

@xgustavoh
Copy link
Author

I'll test here now, and I'll give you feedback.

On the problem of metadata arriving before the audio, I have this same problem, but I made a correction in JS.

What happens is, this type of metadata update check checks the data that has arrived from the network. The correct would be to check the data before going to the decoder of the audio, because there is a radio (same as mine) that has a predefined buffer of X seconds, the verification via Network does not take into account this Buffer, while checking before the decoder would take into consideration.

Note: Do you want me to start putting the message in Portuguese after the English text?

@xgustavoh
Copy link
Author

During my test it was possible to detect the error java.lang.NoClassDefFoundError: Failed resolution of: Lsaschpe/exoplayer2/ext/icy/IcyHttpDataSource$IcyMetadataListener;

That's exactly what you said, when the icy option is not enabled the application stopped responding because it did not have the IcyHttpDataSource class imported.

I do not know if the way I did the fix was the best, but so the error stopped.

Maybe it will take a while for me to get used to the "writing mode" of this project, so I'll beg to apologize.

@Guichaguri
Copy link
Collaborator

We finally merged #465, but I think I'll be holding this PR a little longer.

The developer from the icy extension pushed a PR to ExoPlayer (google/ExoPlayer#4993), which has been approved and it's currently on their dev branch. Once it's released, we can move to a new, clean solution, that also supports ID3, SCTE35 and EMSG metadata, and no new extensions will be required.

@xgustavoh
Copy link
Author

Closed / Discontinued.
Replaced with #552 (Best Performance).

@xgustavoh xgustavoh closed this Apr 23, 2019
@xgustavoh xgustavoh deleted the icy-metadata branch May 3, 2019 18:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants