Add Icy metadata support on Android (#78)
* Add Icy "info" metadata to Android playback events * Add IcyMetadata stream to the Flutter module * Update ExoPlayer to 2.11.4 * Use Player.EventListener.onTracksChanged to retrieve IcyHeaders * Iterate over each track of trackGroups to look for IcyHeaders
This commit is contained in:
parent
ea4be9f9ad
commit
0f57b69ead
3 changed files with 143 additions and 15 deletions
|
@ -7,11 +7,18 @@ import com.google.android.exoplayer2.ExoPlaybackException;
|
|||
import com.google.android.exoplayer2.Player;
|
||||
import com.google.android.exoplayer2.PlaybackParameters;
|
||||
import com.google.android.exoplayer2.SimpleExoPlayer;
|
||||
import com.google.android.exoplayer2.metadata.Metadata;
|
||||
import com.google.android.exoplayer2.metadata.MetadataOutput;
|
||||
import com.google.android.exoplayer2.metadata.icy.IcyHeaders;
|
||||
import com.google.android.exoplayer2.metadata.icy.IcyInfo;
|
||||
import com.google.android.exoplayer2.source.ClippingMediaSource;
|
||||
import com.google.android.exoplayer2.source.MediaSource;
|
||||
import com.google.android.exoplayer2.source.ProgressiveMediaSource;
|
||||
import com.google.android.exoplayer2.source.TrackGroup;
|
||||
import com.google.android.exoplayer2.source.TrackGroupArray;
|
||||
import com.google.android.exoplayer2.source.dash.DashMediaSource;
|
||||
import com.google.android.exoplayer2.source.hls.HlsMediaSource;
|
||||
import com.google.android.exoplayer2.trackselection.TrackSelectionArray;
|
||||
import com.google.android.exoplayer2.upstream.DataSource;
|
||||
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
|
||||
import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory;
|
||||
|
@ -28,17 +35,14 @@ import io.flutter.plugin.common.MethodChannel.Result;
|
|||
import io.flutter.plugin.common.PluginRegistry.Registrar;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import java.util.Collections;
|
||||
import android.content.Context;
|
||||
import android.net.Uri;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class AudioPlayer implements MethodCallHandler, Player.EventListener {
|
||||
public class AudioPlayer implements MethodCallHandler, Player.EventListener, MetadataOutput {
|
||||
static final String TAG = "AudioPlayer";
|
||||
|
||||
private final Registrar registrar;
|
||||
|
@ -64,6 +68,8 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener {
|
|||
private boolean buffering;
|
||||
private boolean justConnected;
|
||||
private MediaSource mediaSource;
|
||||
private IcyInfo icyInfo;
|
||||
private IcyHeaders icyHeaders;
|
||||
|
||||
private final SimpleExoPlayer player;
|
||||
private final Handler handler = new Handler();
|
||||
|
@ -109,6 +115,7 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener {
|
|||
state = PlaybackState.none;
|
||||
|
||||
player = new SimpleExoPlayer.Builder(context).build();
|
||||
player.addMetadataOutput(this);
|
||||
player.addListener(this);
|
||||
}
|
||||
|
||||
|
@ -117,6 +124,38 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener {
|
|||
handler.post(bufferWatcher);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMetadata(Metadata metadata) {
|
||||
for (int i = 0; i < metadata.length(); i++) {
|
||||
final Metadata.Entry entry = metadata.get(i);
|
||||
if (entry instanceof IcyInfo) {
|
||||
icyInfo = (IcyInfo) entry;
|
||||
broadcastPlaybackEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
|
||||
for (int i = 0; i < trackGroups.length; i++) {
|
||||
TrackGroup trackGroup = trackGroups.get(i);
|
||||
|
||||
for (int j = 0; j < trackGroup.length; j++) {
|
||||
Metadata metadata = trackGroup.getFormat(j).metadata;
|
||||
|
||||
if (metadata != null) {
|
||||
for (int k = 0; k < metadata.length(); k++) {
|
||||
final Metadata.Entry entry = metadata.get(k);
|
||||
if (entry instanceof IcyHeaders) {
|
||||
icyHeaders = (IcyHeaders) entry;
|
||||
broadcastPlaybackEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
|
||||
switch (playbackState) {
|
||||
|
@ -261,6 +300,32 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener {
|
|||
event.add(updatePosition = getCurrentPosition());
|
||||
event.add(updateTime = System.currentTimeMillis());
|
||||
event.add(Math.max(updatePosition, bufferedPosition));
|
||||
|
||||
final ArrayList<Object> icyData = new ArrayList<>();
|
||||
final ArrayList<String> info;
|
||||
final ArrayList<Object> headers;
|
||||
if (icyInfo != null) {
|
||||
info = new ArrayList<>();
|
||||
info.add(icyInfo.title);
|
||||
info.add(icyInfo.url);
|
||||
} else {
|
||||
info = new ArrayList<>(Collections.nCopies(2, null));
|
||||
}
|
||||
if (icyHeaders != null) {
|
||||
headers = new ArrayList<>();
|
||||
headers.add(icyHeaders.bitrate);
|
||||
headers.add(icyHeaders.genre);
|
||||
headers.add(icyHeaders.name);
|
||||
headers.add(icyHeaders.metadataInterval);
|
||||
headers.add(icyHeaders.url);
|
||||
headers.add(icyHeaders.isPublic);
|
||||
} else {
|
||||
headers = new ArrayList<>(Collections.nCopies(6, null));
|
||||
}
|
||||
icyData.add(info);
|
||||
icyData.add(headers);
|
||||
event.add(icyData);
|
||||
|
||||
if (eventSink != null) {
|
||||
eventSink.success(event);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue