mirror of
https://github.com/androidx/media.git
synced 2025-05-05 06:30:24 +08:00
Pass the raw ICY metadata through IcyInfo
The ICY 'spec' isn't really clear/tight enough to do anything more specific than this I think. Issue:#6476 PiperOrigin-RevId: 272405322
This commit is contained in:
parent
15df31b995
commit
e0c8cbe21e
@ -5,6 +5,8 @@
|
||||
* Add `Player.onPlaybackSuppressionReasonChanged` to allow listeners to
|
||||
detect playbacks suppressions (e.g. audio focus loss) directly
|
||||
([#6203](https://github.com/google/ExoPlayer/issues/6203)).
|
||||
* Expose the raw ICY metadata through `IcyInfo`
|
||||
([#6476](https://github.com/google/ExoPlayer/issues/6476)).
|
||||
|
||||
### 2.10.5 (2019-09-20) ###
|
||||
|
||||
|
@ -15,12 +15,10 @@
|
||||
*/
|
||||
package com.google.android.exoplayer2.metadata.icy;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.metadata.MetadataDecoder;
|
||||
import com.google.android.exoplayer2.metadata.MetadataInputBuffer;
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.regex.Matcher;
|
||||
@ -36,7 +34,6 @@ public final class IcyDecoder implements MetadataDecoder {
|
||||
private static final String STREAM_KEY_URL = "streamurl";
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
@SuppressWarnings("ByteBufferBackingArray")
|
||||
public Metadata decode(MetadataInputBuffer inputBuffer) {
|
||||
ByteBuffer buffer = inputBuffer.data;
|
||||
@ -45,7 +42,6 @@ public final class IcyDecoder implements MetadataDecoder {
|
||||
return decode(Util.fromUtf8Bytes(data, 0, length));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@VisibleForTesting
|
||||
/* package */ Metadata decode(String metadata) {
|
||||
String name = null;
|
||||
@ -62,12 +58,9 @@ public final class IcyDecoder implements MetadataDecoder {
|
||||
case STREAM_KEY_URL:
|
||||
url = value;
|
||||
break;
|
||||
default:
|
||||
Log.w(TAG, "Unrecognized ICY tag: " + name);
|
||||
break;
|
||||
}
|
||||
index = matcher.end();
|
||||
}
|
||||
return (name != null || url != null) ? new Metadata(new IcyInfo(name, url)) : null;
|
||||
return new Metadata(new IcyInfo(metadata, name, url));
|
||||
}
|
||||
}
|
||||
|
@ -19,26 +19,35 @@ import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
||||
/** ICY in-stream information. */
|
||||
public final class IcyInfo implements Metadata.Entry {
|
||||
|
||||
/** The complete metadata string used to construct this IcyInfo. */
|
||||
public final String rawMetadata;
|
||||
/** The stream title if present, or {@code null}. */
|
||||
@Nullable public final String title;
|
||||
/** The stream title if present, or {@code null}. */
|
||||
/** The stream URL if present, or {@code null}. */
|
||||
@Nullable public final String url;
|
||||
|
||||
/**
|
||||
* Construct a new IcyInfo from the source metadata string, and optionally a StreamTitle &
|
||||
* StreamUrl that have been extracted.
|
||||
*
|
||||
* @param rawMetadata See {@link #rawMetadata}.
|
||||
* @param title See {@link #title}.
|
||||
* @param url See {@link #url}.
|
||||
*/
|
||||
public IcyInfo(@Nullable String title, @Nullable String url) {
|
||||
public IcyInfo(String rawMetadata, @Nullable String title, @Nullable String url) {
|
||||
this.rawMetadata = rawMetadata;
|
||||
this.title = title;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
/* package */ IcyInfo(Parcel in) {
|
||||
rawMetadata = Assertions.checkNotNull(in.readString());
|
||||
title = in.readString();
|
||||
url = in.readString();
|
||||
}
|
||||
@ -52,26 +61,27 @@ public final class IcyInfo implements Metadata.Entry {
|
||||
return false;
|
||||
}
|
||||
IcyInfo other = (IcyInfo) obj;
|
||||
return Util.areEqual(title, other.title) && Util.areEqual(url, other.url);
|
||||
// title & url are derived from rawMetadata, so no need to include them in the comparison.
|
||||
return Util.areEqual(rawMetadata, other.rawMetadata);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17;
|
||||
result = 31 * result + (title != null ? title.hashCode() : 0);
|
||||
result = 31 * result + (url != null ? url.hashCode() : 0);
|
||||
return result;
|
||||
// title & url are derived from rawMetadata, so no need to include them in the hash.
|
||||
return rawMetadata.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ICY: title=\"" + title + "\", url=\"" + url + "\"";
|
||||
return String.format(
|
||||
"ICY: title=\"%s\", url=\"%s\", rawMetadata=\"%s\"", title, url, rawMetadata);
|
||||
}
|
||||
|
||||
// Parcelable implementation.
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeString(rawMetadata);
|
||||
dest.writeString(title);
|
||||
dest.writeString(url);
|
||||
}
|
||||
|
@ -29,10 +29,12 @@ public final class IcyDecoderTest {
|
||||
@Test
|
||||
public void decode() {
|
||||
IcyDecoder decoder = new IcyDecoder();
|
||||
Metadata metadata = decoder.decode("StreamTitle='test title';StreamURL='test_url';");
|
||||
String icyContent = "StreamTitle='test title';StreamURL='test_url';";
|
||||
Metadata metadata = decoder.decode(icyContent);
|
||||
|
||||
assertThat(metadata.length()).isEqualTo(1);
|
||||
IcyInfo streamInfo = (IcyInfo) metadata.get(0);
|
||||
assertThat(streamInfo.rawMetadata).isEqualTo(icyContent);
|
||||
assertThat(streamInfo.title).isEqualTo("test title");
|
||||
assertThat(streamInfo.url).isEqualTo("test_url");
|
||||
}
|
||||
@ -40,21 +42,39 @@ public final class IcyDecoderTest {
|
||||
@Test
|
||||
public void decode_titleOnly() {
|
||||
IcyDecoder decoder = new IcyDecoder();
|
||||
Metadata metadata = decoder.decode("StreamTitle='test title';");
|
||||
String icyContent = "StreamTitle='test title';";
|
||||
Metadata metadata = decoder.decode(icyContent);
|
||||
|
||||
assertThat(metadata.length()).isEqualTo(1);
|
||||
IcyInfo streamInfo = (IcyInfo) metadata.get(0);
|
||||
assertThat(streamInfo.rawMetadata).isEqualTo(icyContent);
|
||||
assertThat(streamInfo.title).isEqualTo("test title");
|
||||
assertThat(streamInfo.url).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decode_emptyTitle() {
|
||||
public void decode_extraTags() {
|
||||
String icyContent =
|
||||
"StreamTitle='test title';StreamURL='test_url';CustomTag|withWeirdSeparator";
|
||||
IcyDecoder decoder = new IcyDecoder();
|
||||
Metadata metadata = decoder.decode("StreamTitle='';StreamURL='test_url';");
|
||||
Metadata metadata = decoder.decode(icyContent);
|
||||
|
||||
assertThat(metadata.length()).isEqualTo(1);
|
||||
IcyInfo streamInfo = (IcyInfo) metadata.get(0);
|
||||
assertThat(streamInfo.rawMetadata).isEqualTo(icyContent);
|
||||
assertThat(streamInfo.title).isEqualTo("test title");
|
||||
assertThat(streamInfo.url).isEqualTo("test_url");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decode_emptyTitle() {
|
||||
IcyDecoder decoder = new IcyDecoder();
|
||||
String icyContent = "StreamTitle='';StreamURL='test_url';";
|
||||
Metadata metadata = decoder.decode(icyContent);
|
||||
|
||||
assertThat(metadata.length()).isEqualTo(1);
|
||||
IcyInfo streamInfo = (IcyInfo) metadata.get(0);
|
||||
assertThat(streamInfo.rawMetadata).isEqualTo(icyContent);
|
||||
assertThat(streamInfo.title).isEmpty();
|
||||
assertThat(streamInfo.url).isEqualTo("test_url");
|
||||
}
|
||||
@ -62,10 +82,12 @@ public final class IcyDecoderTest {
|
||||
@Test
|
||||
public void decode_semiColonInTitle() {
|
||||
IcyDecoder decoder = new IcyDecoder();
|
||||
Metadata metadata = decoder.decode("StreamTitle='test; title';StreamURL='test_url';");
|
||||
String icyContent = "StreamTitle='test; title';StreamURL='test_url';";
|
||||
Metadata metadata = decoder.decode(icyContent);
|
||||
|
||||
assertThat(metadata.length()).isEqualTo(1);
|
||||
IcyInfo streamInfo = (IcyInfo) metadata.get(0);
|
||||
assertThat(streamInfo.rawMetadata).isEqualTo(icyContent);
|
||||
assertThat(streamInfo.title).isEqualTo("test; title");
|
||||
assertThat(streamInfo.url).isEqualTo("test_url");
|
||||
}
|
||||
@ -73,10 +95,12 @@ public final class IcyDecoderTest {
|
||||
@Test
|
||||
public void decode_quoteInTitle() {
|
||||
IcyDecoder decoder = new IcyDecoder();
|
||||
Metadata metadata = decoder.decode("StreamTitle='test' title';StreamURL='test_url';");
|
||||
String icyContent = "StreamTitle='test' title';StreamURL='test_url';";
|
||||
Metadata metadata = decoder.decode(icyContent);
|
||||
|
||||
assertThat(metadata.length()).isEqualTo(1);
|
||||
IcyInfo streamInfo = (IcyInfo) metadata.get(0);
|
||||
assertThat(streamInfo.rawMetadata).isEqualTo(icyContent);
|
||||
assertThat(streamInfo.title).isEqualTo("test' title");
|
||||
assertThat(streamInfo.url).isEqualTo("test_url");
|
||||
}
|
||||
@ -84,19 +108,25 @@ public final class IcyDecoderTest {
|
||||
@Test
|
||||
public void decode_lineTerminatorInTitle() {
|
||||
IcyDecoder decoder = new IcyDecoder();
|
||||
Metadata metadata = decoder.decode("StreamTitle='test\r\ntitle';StreamURL='test_url';");
|
||||
String icyContent = "StreamTitle='test\r\ntitle';StreamURL='test_url';";
|
||||
Metadata metadata = decoder.decode(icyContent);
|
||||
|
||||
assertThat(metadata.length()).isEqualTo(1);
|
||||
IcyInfo streamInfo = (IcyInfo) metadata.get(0);
|
||||
assertThat(streamInfo.rawMetadata).isEqualTo(icyContent);
|
||||
assertThat(streamInfo.title).isEqualTo("test\r\ntitle");
|
||||
assertThat(streamInfo.url).isEqualTo("test_url");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decode_notIcy() {
|
||||
public void decode_noReconisedHeaders() {
|
||||
IcyDecoder decoder = new IcyDecoder();
|
||||
Metadata metadata = decoder.decode("NotIcyData");
|
||||
|
||||
assertThat(metadata).isNull();
|
||||
assertThat(metadata.length()).isEqualTo(1);
|
||||
IcyInfo streamInfo = (IcyInfo) metadata.get(0);
|
||||
assertThat(streamInfo.rawMetadata).isEqualTo("NotIcyData");
|
||||
assertThat(streamInfo.title).isNull();
|
||||
assertThat(streamInfo.url).isNull();
|
||||
}
|
||||
}
|
||||
|
@ -24,11 +24,11 @@ import org.junit.runner.RunWith;
|
||||
|
||||
/** Test for {@link IcyInfo}. */
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public final class IcyStreamInfoTest {
|
||||
public final class IcyInfoTest {
|
||||
|
||||
@Test
|
||||
public void parcelEquals() {
|
||||
IcyInfo streamInfo = new IcyInfo("name", "url");
|
||||
IcyInfo streamInfo = new IcyInfo("StreamName='name';StreamUrl='url'", "name", "url");
|
||||
// Write to parcel.
|
||||
Parcel parcel = Parcel.obtain();
|
||||
streamInfo.writeToParcel(parcel, 0);
|
Loading…
x
Reference in New Issue
Block a user