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

Added an event that triggers when metadata is received from the track source #552

Merged
merged 3 commits into from
May 1, 2019

Conversation

Guichaguri
Copy link
Collaborator

This PR adds the playback-metadata-received event, which is fired whenever ID3 Tags, Icy Metadata or Icy Headers are received with the following parameters:

Param Type Description
source string The metadata source (id3, icy or icy-headers)
title string The track title. Might be null
url string The track url. Might be null
artist string The track artist. Might be null
album string The track album. Might be null
date string The track date. Might be null
genre string The track genre. Might be null

This PR closes #192, and supersedes #384

Implementation Details

ID3 Tags

The parameters are filled from the following ID3 tags:

Parameter ID3 Tags
title TIT2
album TALB or TOAL
artist TOPE
date TDRC
url WOAS, WORS or WOAF

Icy Metadata

The parameters are filled from the following properties:

Parameter Property
title StreamTitle¹
artist StreamTitle¹
url StreamUrl

¹ - The module parses the StreamTitle string splitting the first " - ". The first part is set as the artist and the second part is set as title. When there is no occurrences, the whole string is set as title.

Icy Headers

The parameters are filled from the following headers:

Parameter Header
title icy-name
genre icy-genre
url icy-url

@Guichaguri
Copy link
Collaborator Author

@xgustavoh can you take a look?

@xgustavoh
Copy link

xgustavoh commented Apr 21, 2019

@Guichaguri , I can, I'll create a test project to be analyzing and identify if everything is working perfectly!

Edit:
I just did the initial test here, apparently the delay problem was corrected, and it worked perfectly on my streaming(MP3 - 192Kbps).

Tomorrow I'll test more deeply, but so far it's working perfectly!

@xgustavoh
Copy link

xgustavoh commented Apr 22, 2019

Good night @Guichaguri,
I spent all day testing to give you a good feedback on the subject, so come on:

It worked perfectly within my environment, but I detected a small problem, In OGG - codec not working.

Edit¹: Icy headers not working. When reading the code I noticed that the headers never sends onMetaData event, apparently a ExoPlayer error, can not say.

My tests:

Audio Codec Bitrate Icy-Headers Connect Icy-Metadata Change music (Buffer ON) Change music (Buffer OFF)
OGG 500Kbps Fail Fail Fail Fail
OGG 159Kbps Fail Fail Fail Fail
MP3 320Kbps Fail Success Success Success
MP3 192Kbps Fail Success Success Success
AAC 64Kbps Fail Success Success Success
AAC 32Kbps Fail Success Success Success

Note: When the bitrate is smaller, it may be that when the music changes it will take a while to receive the event, but this is not an error, that is correct! Because the metadata is sent in range of X bytes.

Tested configuration playlist.json (I have removed the URL streaming OGG):

[
  {
    "id": "1111",
    "url": "https://live.hunter.fm/rock320",
    "title": "The Rock Channel (320Kbps - MP3)",
    "artist": "Hunter.FM",
    "artwork": "https://cdn.hunter.fm/image/thumb/station/default.jpg"
  },
  {
    "id": "2222",
    "url": "https://live.hunter.fm/country",
    "title": "O Canal Sertanejo (192Kbps - MP3)",
    "artist": "Hunter.FM",
    "artwork": "https://cdn.hunter.fm/image/thumb/station/sertanejo-first/200x200ht.jpg"
  },
  {
    "id": "3333",
    "url": "https://live.hunter.fm/mpop2k",
    "title": "The Pop2k Hitz Channel (64Kbps - AAC)",
    "artist": "Hunter.FM",
    "artwork": "https://cdn.hunter.fm/image/thumb/station/pop2k-first/200x200ht.jpg"
  },
  {
    "id": "4444",
    "url": "https://live.hunter.fm/80s32",
    "title": "The 80s Channel (32Kbps - AAC)",
    "artist": "Hunter.FM",
    "artwork": "https://cdn.hunter.fm/image/thumb/station/80s-first/200x200ht.jpg"
  }
]

@maendamedia
Copy link

Is it correct we cannot test this yet? As when i try the unstable branche i get the error as attached

Schermafbeelding 2019-04-25 om 20 53 57

@xgustavoh
Copy link

xgustavoh commented Apr 25, 2019

@maendamedia This implementation is only for Android (initially).
Apparently you took the test in IOS, correct?

Note¹: the correct event name is playback-metadata-received
Note²: To test you have to install using npm + git (or yarn + git), being a test it is recommended to use a "branch" only to test this implementation, thus not affecting your current environment.

@maendamedia
Copy link

@maendamedia This implementation is only for Android (initially).
Apparently you took the test in IOS, correct?

Note¹: the correct event name is playback-metadata-received
Note²: To test you have to install using npm + git (or yarn + git), being a test it is recommended to use a "branch" only to test this implementation, thus not affecting your current environment.

Ok, yes it was iOS indeed :)
But also on Android it does not work. I guess i implement it wrong. Is there a good example somewhere?

@xgustavoh
Copy link

@maendamedia This implementation is only for Android (initially).
Apparently you took the test in IOS, correct?
Note¹: the correct event name is playback-metadata-received
Note²: To test you have to install using npm + git (or yarn + git), being a test it is recommended to use a "branch" only to test this implementation, thus not affecting your current environment.

Ok, yes it was iOS indeed :)
But also on Android it does not work. I guess i implement it wrong. Is there a good example somewhere?

My teste: react-native-track-player-example-icecast

@Guichaguri
Copy link
Collaborator Author

@xgustavoh As for OGG, that issue can either be caused by a bug in ExoPlayer or by the track not being properly encoded. Can you send an OGG stream URL where it doesn't work?

Let me know whether 82b8cec fixes the icy headers for you.

@xgustavoh
Copy link

xgustavoh commented May 1, 2019

@Guichaguri, I took the test here, the icy-headers is now received.

About OGG really is a bug in ExoPlayer, because I use AIMP on my computer to test the metadata and it gets perfectly, while on the mobile does not receive.

URL Stream: http://ice2.hunterfm.com:2001/ogg
Note: This URL is not using the SSL certificate (HTTPS) because it is a test environment, in case you need HTTPS I can configure it.

------------ AIMP Vs ExoPlayer
image
image
Note that ExoPlayer does not issue the update event.

@Guichaguri
Copy link
Collaborator Author

Guichaguri commented May 1, 2019

There is something different with the OGG stream.

Basically, the player sends the icy-metadata header in the HTTP request and the server returns the icy-metaint header which is the interval of bytes in which the metadata will be reported. Read in this short page more about how the icy protocol works.

For the OGG URL you've sent, these are the headers returned:

{ server: 'HunterCast 2.2',
  date: 'Wed, 01 May 2019 20:34:58 GMT',
  'content-type': 'application/ogg',
  'cache-control': 'no-cache',
  expires: 'Mon, 26 Jul 1997 05:00:00 GMT',
  pragma: 'no-cache',
  'ice-audio-info': 'ice-samplerate=44100;ice-quality=4,99;ice-channels=2',
  'icy-br': 'Quality 4,99',
  'icy-description': 'My station description',
  'icy-genre': 'Various',
  'icy-name': 'My Station name',
  'icy-pub': '1',
  'icy-url': 'http://www.audiorealm.com' }

Here are the headers for the MP3 stream:

{ server: 'Icecast 2.4.2',
  date: 'Wed, 01 May 2019 20:42:04 GMT',
  'content-type': 'audio/mpeg',
  'cache-control': 'no-cache',
  expires: 'Mon, 26 Jul 1997 05:00:00 GMT',
  pragma: 'no-cache',
  'icy-br': '320, 320',
  'ice-audio-info': 'ice-samplerate=44100;ice-bitrate=320;ice-channels=2',
  'icy-genre': 'Rock',
  'icy-name': 'HUNTER.FM -=[: O Canal Rock :]=-',
  'icy-pub': '1',
  'icy-url': 'http://hunter.fm',
  'icy-metaint': '16000',
  'strict-transport-security': 'max-age=31536000; includeSubDomains; preload' }

@Guichaguri
Copy link
Collaborator Author

Guichaguri commented May 1, 2019

After researching a little bit, I think OGG streams use VorbisComment instead.

After analyzing the stream using the music-metadata module, I've confirmed it is indeed Vorbis metadata instead of Icy:

"vorbis": [
    {
        "id": "ENCODER",
        "value": "SAM technology"
    },
    {
        "id": "ARTIST",
        "value": "Lauv & Troye Sivan"
    },
    {
        "id": "TITLE",
        "value": "i'm so tired"
    }
]

Here's an ExoPlayer feature request for reading VorbisComment: google/ExoPlayer#5527

Edit: Documentation about the VorbisComment format can be found here.

@xgustavoh
Copy link

xgustavoh commented May 1, 2019

@Guichaguri.

I really had not noticed that the header was different, now that you've commented, I've noticed that even the AIMP does not get icy-metaint.

HTTP / 1.0 200 OK
Server: HunterCast 2.2
Date: Wed, 01 May 2019 17:55:59 GMT
Content-Type: application / ogg
Cache-Control: no-cache
Expires: Mon, 26 Jul 1997 05:00:00 GMT
Pragma: no-cache
ice-audio-info: ice-samplerate = 44100; ice-quality = 4.99; ice-channels = 2
icy-br: Quality 4,99
icy-description: My station description
icy-genre: Various
icy-name: My Station name
icy-pub: 1
icy-url: http://www.audiorealm.com

So following the logic, both FLAC and OGG (which use VORBIS_COMMENT) will not work initially, it will be necessary to wait for the implementation of ExoPlayer.

@Guichaguri Guichaguri merged commit 61f7a8e into dev May 1, 2019
@Guichaguri
Copy link
Collaborator Author

I've merged it. We'll add support for new metadata types whenever ExoPlayer adds them. For now, this is enough for most tracks.

@Guichaguri Guichaguri deleted the feat/source-metadata branch May 1, 2019 22:52
@xgustavoh
Copy link

Only one question pertaining to handleId3Metadata and handleIcyMetadata, separating in 2 functions, and doing 2 for all metadata, is not an 'unnecessary' computational use?

Although, considering that usually only comes 1 metadata per made, the for is not used more than once ..... There is doubt 🤔

@Guichaguri
Copy link
Collaborator Author

Guichaguri commented May 1, 2019

I've separated them mostly for readability reasons, but the change also makes them not conflict with each other.

Let's say you have a mp3 stream that has both ID3 tags and ICY metadata, the older code would only trigger the event once, being a mix of the ID3 tags and the ICY metadata. Now, it triggers the event twice: one for the ID3 tags and another one for the ICY metadata.

Considering there is usually no ID3 tags in icy streams, it shouldn't be a problem at all, but it might become one as we implement new metadata formats.

As for the computational usage, the difference is too small even for a benchmark to notice.

@Guichaguri
Copy link
Collaborator Author

Just as an update from this PR, ExoPlayer recently added support for both Vorbis Comments and QuickTime metadata, I've added support for both of them in v2: 4139370

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.

Add support to icy streams
3 participants