mirror of
https://github.com/gabehf/Fladder.git
synced 2026-03-07 13:38:13 -08:00
fix: Incorrect progress updating for native player
This commit is contained in:
parent
fa61ce2e40
commit
a3ccb6009c
6 changed files with 57 additions and 32 deletions
|
|
@ -714,8 +714,8 @@ interface NativeVideoActivity {
|
|||
}
|
||||
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
||||
interface VideoPlayerApi {
|
||||
fun sendPlayableModel(playableData: PlayableData): Boolean
|
||||
fun open(url: String, play: Boolean)
|
||||
fun sendPlayableModel(playableData: PlayableData, callback: (Result<Boolean>) -> Unit)
|
||||
fun open(url: String, play: Boolean, callback: (Result<Boolean>) -> Unit)
|
||||
fun setLooping(looping: Boolean)
|
||||
/** Sets the volume, with 0.0 being muted and 1.0 being full volume. */
|
||||
fun setVolume(volume: Double)
|
||||
|
|
@ -743,12 +743,15 @@ interface VideoPlayerApi {
|
|||
channel.setMessageHandler { message, reply ->
|
||||
val args = message as List<Any?>
|
||||
val playableDataArg = args[0] as PlayableData
|
||||
val wrapped: List<Any?> = try {
|
||||
listOf(api.sendPlayableModel(playableDataArg))
|
||||
} catch (exception: Throwable) {
|
||||
VideoPlayerHelperPigeonUtils.wrapError(exception)
|
||||
api.sendPlayableModel(playableDataArg) { result: Result<Boolean> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
reply.reply(VideoPlayerHelperPigeonUtils.wrapError(error))
|
||||
} else {
|
||||
val data = result.getOrNull()
|
||||
reply.reply(VideoPlayerHelperPigeonUtils.wrapResult(data))
|
||||
}
|
||||
}
|
||||
reply.reply(wrapped)
|
||||
}
|
||||
} else {
|
||||
channel.setMessageHandler(null)
|
||||
|
|
@ -761,13 +764,15 @@ interface VideoPlayerApi {
|
|||
val args = message as List<Any?>
|
||||
val urlArg = args[0] as String
|
||||
val playArg = args[1] as Boolean
|
||||
val wrapped: List<Any?> = try {
|
||||
api.open(urlArg, playArg)
|
||||
listOf(null)
|
||||
} catch (exception: Throwable) {
|
||||
VideoPlayerHelperPigeonUtils.wrapError(exception)
|
||||
api.open(urlArg, playArg) { result: Result<Boolean> ->
|
||||
val error = result.exceptionOrNull()
|
||||
if (error != null) {
|
||||
reply.reply(VideoPlayerHelperPigeonUtils.wrapError(error))
|
||||
} else {
|
||||
val data = result.getOrNull()
|
||||
reply.reply(VideoPlayerHelperPigeonUtils.wrapResult(data))
|
||||
}
|
||||
}
|
||||
reply.reply(wrapped)
|
||||
}
|
||||
} else {
|
||||
channel.setMessageHandler(null)
|
||||
|
|
|
|||
|
|
@ -26,18 +26,23 @@ class VideoPlayerImplementation(
|
|||
var player: ExoPlayer? = null
|
||||
val playbackData: MutableStateFlow<PlayableData?> = MutableStateFlow(null)
|
||||
|
||||
override fun sendPlayableModel(playableData: PlayableData): Boolean {
|
||||
override fun sendPlayableModel(
|
||||
playableData: PlayableData,
|
||||
callback: (Result<Boolean>) -> Unit
|
||||
) {
|
||||
try {
|
||||
println("Send playable data")
|
||||
playbackData.value = playableData
|
||||
return true
|
||||
callback(Result.success(true))
|
||||
return
|
||||
} catch (e: Exception) {
|
||||
println("Error loading data $e")
|
||||
return false
|
||||
callback(Result.success(false))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
override fun open(url: String, play: Boolean) {
|
||||
override fun open(url: String, play: Boolean, callback: (Result<Boolean>) -> Unit) {
|
||||
Handler(Looper.getMainLooper()).postDelayed(delayInMillis = 1.seconds.inWholeMilliseconds) {
|
||||
try {
|
||||
playbackData.value?.let {
|
||||
|
|
@ -67,17 +72,21 @@ class VideoPlayerImplementation(
|
|||
player?.prepare()
|
||||
|
||||
val startPosition = playbackData.value?.startPosition ?: 0L
|
||||
if (startPosition > 0) {
|
||||
if (startPosition > 0L) {
|
||||
player?.seekTo(startPosition)
|
||||
|
||||
player?.playWhenReady = play
|
||||
}
|
||||
player?.playWhenReady = play
|
||||
callback(Result.success(true))
|
||||
return@postDelayed
|
||||
} catch (e: Exception) {
|
||||
println("Error playing video $e")
|
||||
callback(Result.success(false))
|
||||
return@postDelayed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun setLooping(looping: Boolean) {
|
||||
player?.repeatMode = if (looping) Player.REPEAT_MODE_ONE else Player.REPEAT_MODE_OFF
|
||||
}
|
||||
|
|
@ -110,10 +119,9 @@ class VideoPlayerImplementation(
|
|||
player = exoPlayer
|
||||
//exoPlayer initializes after the playbackData is set for the first load
|
||||
playbackData.value?.let {
|
||||
sendPlayableModel(it)
|
||||
VideoPlayerObject.setAudioTrackIndex(it.defaultAudioTrack.toInt(), true)
|
||||
VideoPlayerObject.setSubtitleTrackIndex(it.defaultSubtrack.toInt(), true)
|
||||
open(it.url, true)
|
||||
open(it.url, true, callback = {})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -911,7 +911,7 @@ class VideoPlayerApi {
|
|||
}
|
||||
}
|
||||
|
||||
Future<void> open(String url, bool play) async {
|
||||
Future<bool> open(String url, bool play) async {
|
||||
final String pigeonVar_channelName = 'dev.flutter.pigeon.nl_jknaapen_fladder.video.VideoPlayerApi.open$pigeonVar_messageChannelSuffix';
|
||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||
pigeonVar_channelName,
|
||||
|
|
@ -929,8 +929,13 @@ class VideoPlayerApi {
|
|||
message: pigeonVar_replyList[1] as String?,
|
||||
details: pigeonVar_replyList[2],
|
||||
);
|
||||
} else if (pigeonVar_replyList[0] == null) {
|
||||
throw PlatformException(
|
||||
code: 'null-error',
|
||||
message: 'Host platform returned null value for non-null return value.',
|
||||
);
|
||||
} else {
|
||||
return;
|
||||
return (pigeonVar_replyList[0] as bool?)!;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -264,7 +264,7 @@ class MediaControlsWrapper extends BaseAudioHandler implements VideoPlayerContro
|
|||
final totalDuration = _player?.lastState.duration;
|
||||
|
||||
// //Small delay so we don't post right after playback/progress update
|
||||
await Future.delayed(const Duration(seconds: 2));
|
||||
await Future.delayed(const Duration(seconds: 1));
|
||||
|
||||
await playbackModel.playbackStopped(position ?? Duration.zero, totalDuration, ref);
|
||||
ref.read(mediaPlaybackProvider.notifier).update((state) => state.copyWith(position: Duration.zero));
|
||||
|
|
|
|||
|
|
@ -15,11 +15,12 @@ import 'package:fladder/wrappers/players/player_states.dart';
|
|||
|
||||
class NativePlayer extends BasePlayer implements VideoPlayerListenerCallback {
|
||||
final player = VideoPlayerApi();
|
||||
final activity = NativeVideoActivity();
|
||||
|
||||
@override
|
||||
Future<void> dispose() async {
|
||||
nativeActivityStarted = false;
|
||||
return NativeVideoActivity().disposeActivity();
|
||||
return activity.disposeActivity();
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -36,7 +37,7 @@ class NativePlayer extends BasePlayer implements VideoPlayerListenerCallback {
|
|||
@override
|
||||
Future<StartResult> open(BuildContext newContext) async {
|
||||
nativeActivityStarted = true;
|
||||
return NativeVideoActivity().launchActivity();
|
||||
return activity.launchActivity();
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -49,7 +50,11 @@ class NativePlayer extends BasePlayer implements VideoPlayerListenerCallback {
|
|||
|
||||
@override
|
||||
Future<void> playOrPause() async {
|
||||
return;
|
||||
if (lastState.playing) {
|
||||
return player.pause();
|
||||
} else {
|
||||
return player.play();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -59,7 +64,7 @@ class NativePlayer extends BasePlayer implements VideoPlayerListenerCallback {
|
|||
|
||||
@override
|
||||
Future<int> setAudioTrack(AudioStreamModel? model, PlaybackModel playbackModel) async {
|
||||
return 0;
|
||||
return model?.index ?? 0;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -67,7 +72,7 @@ class NativePlayer extends BasePlayer implements VideoPlayerListenerCallback {
|
|||
|
||||
@override
|
||||
Future<int> setSubtitleTrack(SubStreamModel? model, PlaybackModel playbackModel) async {
|
||||
return 0;
|
||||
return model?.index ?? 0;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -177,6 +182,6 @@ class NativePlayer extends BasePlayer implements VideoPlayerListenerCallback {
|
|||
),
|
||||
url: model.media?.url ?? "",
|
||||
);
|
||||
player.sendPlayableModel(playableData);
|
||||
await player.sendPlayableModel(playableData);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -184,9 +184,11 @@ abstract class NativeVideoActivity {
|
|||
|
||||
@HostApi()
|
||||
abstract class VideoPlayerApi {
|
||||
@async
|
||||
bool sendPlayableModel(PlayableData playableData);
|
||||
|
||||
void open(String url, bool play);
|
||||
@async
|
||||
bool open(String url, bool play);
|
||||
|
||||
void setLooping(bool looping);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue