Android implementation of platform interface.

This commit is contained in:
Ryan Heise 2020-09-26 23:36:54 +10:00
parent b8ff881ccf
commit 1d7134ff31
2 changed files with 54 additions and 75 deletions

View File

@ -60,10 +60,7 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener, Aud
private EventSink eventSink; private EventSink eventSink;
private ProcessingState processingState; private ProcessingState processingState;
private long updateTime;
private long updatePosition;
private long bufferedPosition; private long bufferedPosition;
private long duration;
private Long start; private Long start;
private Long end; private Long end;
private Long seekPos; private Long seekPos;
@ -210,9 +207,11 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener, Aud
switch (playbackState) { switch (playbackState) {
case Player.STATE_READY: case Player.STATE_READY:
if (prepareResult != null) { if (prepareResult != null) {
duration = getDuration(); long duration = getDuration();
transition(ProcessingState.ready); transition(ProcessingState.ready);
prepareResult.success(duration); Map<String, Object> response = new HashMap<>();
response.put("duration", 1000 * duration);
prepareResult.success(response);
prepareResult = null; prepareResult = null;
} else { } else {
transition(ProcessingState.ready); transition(ProcessingState.ready);
@ -232,7 +231,7 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener, Aud
transition(ProcessingState.completed); transition(ProcessingState.completed);
} }
if (playResult != null) { if (playResult != null) {
playResult.success(null); playResult.success(new HashMap<String, Object>());
playResult = null; playResult = null;
} }
break; break;
@ -279,7 +278,7 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener, Aud
private void completeSeek() { private void completeSeek() {
seekProcessed = false; seekProcessed = false;
seekPos = null; seekPos = null;
seekResult.success(null); seekResult.success(new HashMap<String, Object>());
seekResult = null; seekResult = null;
} }
@ -287,81 +286,62 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener, Aud
public void onMethodCall(final MethodCall call, final Result result) { public void onMethodCall(final MethodCall call, final Result result) {
ensurePlayerInitialized(); ensurePlayerInitialized();
final List<?> args = (List<?>) call.arguments; final Map<?, ?> request = (Map<?, ?>) call.arguments;
try { try {
switch (call.method) { switch (call.method) {
case "load": case "load":
load(getAudioSource(args.get(0)), result); load(getAudioSource(request.get("audioSource")), result);
break; break;
case "play": case "play":
play(result); play(result);
break; break;
case "pause": case "pause":
pause(); pause();
result.success(null); result.success(new HashMap<String, Object>());
break; break;
case "setVolume": case "setVolume":
setVolume((float) ((double) ((Double) args.get(0)))); setVolume((float) ((double) ((Double) request.get("volume"))));
result.success(null); result.success(new HashMap<String, Object>());
break; break;
case "setSpeed": case "setSpeed":
setSpeed((float) ((double) ((Double) args.get(0)))); setSpeed((float) ((double) ((Double) request.get("speed"))));
result.success(null); result.success(new HashMap<String, Object>());
break; break;
case "setLoopMode": case "setLoopMode":
setLoopMode((Integer) args.get(0)); setLoopMode((Integer) request.get("loopMode"));
result.success(null); result.success(new HashMap<String, Object>());
break; break;
case "setShuffleModeEnabled": case "setShuffleModeEnabled":
setShuffleModeEnabled((Boolean) args.get(0)); setShuffleModeEnabled((Integer) request.get("shuffleMode") == 1);
result.success(null); result.success(new HashMap<String, Object>());
break; break;
case "setAutomaticallyWaitsToMinimizeStalling": case "setAutomaticallyWaitsToMinimizeStalling":
result.success(null); result.success(new HashMap<String, Object>());
break; break;
case "seek": case "seek":
Long position = getLong(args.get(0)); Long position = getLong(request.get("position"));
Integer index = (Integer)args.get(1); Integer index = (Integer)request.get("index");
seek(position == null ? C.TIME_UNSET : position, result, index); seek(position == null ? C.TIME_UNSET : position / 1000, result, index);
break; break;
case "dispose": case "dispose":
dispose(); dispose();
result.success(null); result.success(new HashMap<String, Object>());
break; break;
case "concatenating.add": case "concatenatingInsertAll":
concatenating(args.get(0)) concatenating(request.get("id"))
.addMediaSource(getAudioSource(args.get(1)), handler, () -> result.success(null)); .addMediaSources((Integer)request.get("index"), getAudioSources(request.get("children")), handler, () -> result.success(new HashMap<String, Object>()));
break; break;
case "concatenating.insert": case "concatenatingRemoveRange":
concatenating(args.get(0)) concatenating(request.get("id"))
.addMediaSource((Integer)args.get(1), getAudioSource(args.get(2)), handler, () -> result.success(null)); .removeMediaSourceRange((Integer)request.get("startIndex"), (Integer)request.get("endIndex"), handler, () -> result.success(new HashMap<String, Object>()));
break; break;
case "concatenating.addAll": case "concatenatingMove":
concatenating(args.get(0)) concatenating(request.get("id"))
.addMediaSources(getAudioSources(args.get(1)), handler, () -> result.success(null)); .moveMediaSource((Integer)request.get("currentIndex"), (Integer)request.get("newIndex"), handler, () -> result.success(new HashMap<String, Object>()));
break;
case "concatenating.insertAll":
concatenating(args.get(0))
.addMediaSources((Integer)args.get(1), getAudioSources(args.get(2)), handler, () -> result.success(null));
break;
case "concatenating.removeAt":
concatenating(args.get(0))
.removeMediaSource((Integer)args.get(1), handler, () -> result.success(null));
break;
case "concatenating.removeRange":
concatenating(args.get(0))
.removeMediaSourceRange((Integer)args.get(1), (Integer)args.get(2), handler, () -> result.success(null));
break;
case "concatenating.move":
concatenating(args.get(0))
.moveMediaSource((Integer)args.get(1), (Integer)args.get(2), handler, () -> result.success(null));
break;
case "concatenating.clear":
concatenating(args.get(0)).clear(handler, () -> result.success(null));
break; break;
case "setAndroidAudioAttributes": case "setAndroidAudioAttributes":
setAudioAttributes((Map<?, ?>)args.get(0)); setAudioAttributes((Integer)request.get("contentType"), (Integer)request.get("flags"), (Integer)request.get("usage"));
result.success(null); result.success(new HashMap<String, Object>());
break; break;
default: default:
result.notImplemented(); result.notImplemented();
@ -469,7 +449,7 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener, Aud
.setTag(id) .setTag(id)
.createMediaSource(Uri.parse((String)map.get("uri"))); .createMediaSource(Uri.parse((String)map.get("uri")));
case "concatenating": case "concatenating":
MediaSource[] mediaSources = getAudioSourcesArray(map.get("audioSources")); MediaSource[] mediaSources = getAudioSourcesArray(map.get("children"));
return new ConcatenatingMediaSource( return new ConcatenatingMediaSource(
false, // isAtomic false, // isAtomic
(Boolean)map.get("useLazyPreparation"), (Boolean)map.get("useLazyPreparation"),
@ -478,12 +458,12 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener, Aud
case "clipping": case "clipping":
Long start = getLong(map.get("start")); Long start = getLong(map.get("start"));
Long end = getLong(map.get("end")); Long end = getLong(map.get("end"));
return new ClippingMediaSource(getAudioSource(map.get("audioSource")), return new ClippingMediaSource(getAudioSource(map.get("child")),
(start != null ? start : 0) * 1000L, start != null ? start : 0,
(end != null ? end : C.TIME_END_OF_SOURCE) * 1000L); end != null ? end : C.TIME_END_OF_SOURCE);
case "looping": case "looping":
Integer count = (Integer)map.get("count"); Integer count = (Integer)map.get("count");
MediaSource looperChild = getAudioSource(map.get("audioSource")); MediaSource looperChild = getAudioSource(map.get("child"));
LoopingMediaSource looper = new LoopingMediaSource(looperChild, count); LoopingMediaSource looper = new LoopingMediaSource(looperChild, count);
// TODO: store both in a single map // TODO: store both in a single map
loopingChildren.put(looper, looperChild); loopingChildren.put(looper, looperChild);
@ -552,24 +532,26 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener, Aud
} }
} }
private void setAudioAttributes(Map<?, ?> json) { private void setAudioAttributes(int contentType, int flags, int usage) {
ensurePlayerInitialized(); ensurePlayerInitialized();
AudioAttributes.Builder builder = new AudioAttributes.Builder(); AudioAttributes.Builder builder = new AudioAttributes.Builder();
builder.setContentType((Integer)json.get("contentType")); builder.setContentType(contentType);
builder.setFlags((Integer)json.get("flags")); builder.setFlags(flags);
builder.setUsage((Integer)json.get("usage")); builder.setUsage(usage);
//builder.setAllowedCapturePolicy((Integer)json.get("allowedCapturePolicy")); //builder.setAllowedCapturePolicy((Integer)json.get("allowedCapturePolicy"));
player.setAudioAttributes(builder.build()); player.setAudioAttributes(builder.build());
} }
private void broadcastPlaybackEvent() { private void broadcastPlaybackEvent() {
final Map<String, Object> event = new HashMap<String, Object>(); final Map<String, Object> event = new HashMap<String, Object>();
long updatePosition = getCurrentPosition();
long duration = getDuration();
event.put("processingState", processingState.ordinal()); event.put("processingState", processingState.ordinal());
event.put("updatePosition", updatePosition = getCurrentPosition()); event.put("updatePosition", 1000 * updatePosition);
event.put("updateTime", updateTime = System.currentTimeMillis()); event.put("updateTime", System.currentTimeMillis());
event.put("bufferedPosition", Math.max(updatePosition, bufferedPosition)); event.put("bufferedPosition", 1000 * Math.max(updatePosition, bufferedPosition));
event.put("icyMetadata", collectIcyMetadata()); event.put("icyMetadata", collectIcyMetadata());
event.put("duration", duration = getDuration()); event.put("duration", 1000 * getDuration());
event.put("currentIndex", currentIndex); event.put("currentIndex", currentIndex);
event.put("androidAudioSessionId", audioSessionId); event.put("androidAudioSessionId", audioSessionId);
@ -646,13 +628,13 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener, Aud
public void play(Result result) { public void play(Result result) {
if (player.getPlayWhenReady()) return; if (player.getPlayWhenReady()) return;
if (playResult != null) { if (playResult != null) {
playResult.success(null); playResult.success(new HashMap<String, Object>());
} }
playResult = result; playResult = result;
startWatchingBuffer(); startWatchingBuffer();
player.setPlayWhenReady(true); player.setPlayWhenReady(true);
if (processingState == ProcessingState.completed && playResult != null) { if (processingState == ProcessingState.completed && playResult != null) {
playResult.success(null); playResult.success(new HashMap<String, Object>());
playResult = null; playResult = null;
} }
} }
@ -661,7 +643,7 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener, Aud
if (!player.getPlayWhenReady()) return; if (!player.getPlayWhenReady()) return;
player.setPlayWhenReady(false); player.setPlayWhenReady(false);
if (playResult != null) { if (playResult != null) {
playResult.success(null); playResult.success(new HashMap<String, Object>());
playResult = null; playResult = null;
} }
} }
@ -715,7 +697,7 @@ public class AudioPlayer implements MethodCallHandler, Player.EventListener, Aud
private void abortSeek() { private void abortSeek() {
if (seekResult != null) { if (seekResult != null) {
seekResult.success(null); seekResult.success(new HashMap<String, Object>());
seekResult = null; seekResult = null;
seekPos = null; seekPos = null;
seekProcessed = false; seekProcessed = false;

View File

@ -28,16 +28,13 @@ public class MainMethodCallHandler implements MethodCallHandler {
public void onMethodCall(MethodCall call, @NonNull Result result) { public void onMethodCall(MethodCall call, @NonNull Result result) {
switch (call.method) { switch (call.method) {
case "init": case "init":
final List<String> ids = call.arguments(); final Map<?, ?> request = call.arguments();
String id = ids.get(0); String id = (String)request.get("id");
players.put(id, new AudioPlayer(applicationContext, messenger, id, players.put(id, new AudioPlayer(applicationContext, messenger, id,
() -> players.remove(id) () -> players.remove(id)
)); ));
result.success(null); result.success(null);
break; break;
case "setIosCategory":
result.success(null);
break;
default: default:
result.notImplemented(); result.notImplemented();
break; break;