Проблема с переключением и буферизацией песен в фоновом режиме iOS с использованием пакета audio_service во FlutterIOS

Программируем под IOS
Ответить Пред. темаСлед. тема
Anonymous
 Проблема с переключением и буферизацией песен в фоновом режиме iOS с использованием пакета audio_service во Flutter

Сообщение Anonymous »

Я работаю над приложением потоковой передачи аудио, используя пакет audio_service во Flutter, и столкнулся с проблемой: переключение песен работает нормально на переднем плане, но когда приложение находится в фоновом режиме, песня не переключается, и аудиоплеер застревает в буферизации. Эта проблема характерна только для iOS, так как приложение отлично работает на Android.
Вот что я сделал на данный момент:
Я настроил фоновые режимы в Info.plist, чтобы разрешить звук и Xcode.
Я реализовал необходимую фоновую задачу для воспроизведения звука, но переключение песен в фоновом режиме не работает должным образом.
Это мой файл songHandler

Код: Выделить всё

import 'dart:developer';

import 'package:audio_service/audio_service.dart';
import 'package:just_audio/just_audio.dart';
import 'package:rxdart/rxdart.dart' as rx;

class SongHandler extends BaseAudioHandler with SeekHandler {
final AudioPlayer audioPlayer = AudioPlayer();
MediaItem? currentMediaItem;
bool hasPrevious = false;
bool hasNext = false;

void _broadcastState() {
mediaItem.add(currentMediaItem);

playbackState.add(playbackState.value.copyWith(
controls: [
if (hasPrevious) MediaControl.skipToPrevious,
if (audioPlayer.playing) MediaControl.pause else MediaControl.play,
if (hasNext) MediaControl.skipToNext,
],
systemActions: {
MediaAction.seek,
MediaAction.seekForward,
MediaAction.seekBackward,
},
processingState: {
ProcessingState.idle: AudioProcessingState.idle,
ProcessingState.loading: AudioProcessingState.loading,
ProcessingState.buffering: AudioProcessingState.buffering,
ProcessingState.ready: AudioProcessingState.ready,
ProcessingState.completed: AudioProcessingState.completed,
}[audioPlayer.processingState]!,
playing: audioPlayer.playing,
updatePosition: audioPlayer.position,
bufferedPosition: audioPlayer.bufferedPosition,
speed: audioPlayer.speed,
queueIndex: 0,
));
}

Future initSong(
AudioSource audioSource,
MediaItem song,
) async {
currentMediaItem = song; // Set current media item
audioPlayer.playbackEventStream.listen((_) => _broadcastState());
await audioPlayer.setAudioSource(audioSource);
play();
}

Future updateAudioSource(AudioSource audioSource, MediaItem song,
{bool? isShowButton = false}) async {
await audioPlayer.setAudioSource(audioSource);

currentMediaItem = song;
hasPrevious = isShowButton ?? false;
hasNext = isShowButton ?? false;
}

@override
Future play() async {
if (currentMediaItem != null) {
await audioPlayer.play();
}
}

@override
Future pause() => audioPlayer.pause();

@override
Future seek(Duration position) => audioPlayer.seek(position);

@override
Future skipToNext() async {
final musicPlayerViewModel = Get.find();
musicPlayerViewModel.moveNextSong();
// Logic to skip to the next song
log('message');
}

@override
Future skipToPrevious() async {
final musicPlayerViewModel = Get.find();
musicPlayerViewModel.movePreviousSong();
// Logic to skip to the previous song
log('message');
}

Stream
 get positionDataStream =>
rx.CombineLatestStream.combine3(
audioPlayer.positionStream,
audioPlayer.bufferedPositionStream,
audioPlayer.durationStream,
(position, bufferedPosition, duration) =>  PositionData(
position: position,
bufferedPosition: bufferedPosition,
duration: duration ?? Duration.zero,
),
);
}
это мой слушатель и функция переключения песен

Код: Выделить всё

  void musicSetupListeners() {
playerStateSubscription?.cancel();
playerStateSubscription =
songHandler.audioPlayer.playerStateStream.listen((state) async {
log('Player state: ${state.processingState}');
switch (state.processingState) {
case ProcessingState.idle:
// Handle idle state if needed
break;
case ProcessingState.loading:
// Handle loading state if needed
break;
case ProcessingState.buffering:
// Handle buffering state if needed
break;
case ProcessingState.ready:
// Handle ready state if needed
break;
case ProcessingState.completed:
await handleCompletion();
break;
}
}, onError: (error) {
log('Stream error: $error');
});
}

Future handleCompletion() async {
await songHandler.pause();
await songHandler.seek(Duration.zero);
await Future.delayed(const Duration(milliseconds: 500), () async {
try {
if (!isProcessingCompletion.value) {
isNewSongLoading.value = true;
isNewSongLoading.refresh();
isProcessingCompletion.value = true;
isProcessingCompletion.refresh();

await songHandler.stop();
await Future.delayed(const Duration(milliseconds: 500), () async {
await _playNextSong(this);
isProcessingCompletion.value = false;
});
}
} catch (e) {
log('Error during completion handling: $e');
}
});
}

Future _playNextSong(MusicPlayerViewModel musicPlayerViewModel) async {
if (isChangeList.value == false) {
if (britanyPlyController.isShuffle.value) {
await britanyPlyController.selectRandomSongs(musicPlayerViewModel);
} else {
await britanyPlyController.selectSequenceSongs(musicPlayerViewModel);
}
} else {
await selectSequenceSongs();
}
Future.delayed(
const Duration(milliseconds: 300),
() {
isNewSongLoading.value = false;
isNewSongLoading.refresh();
},
);

await songHandler.play();
}
Я хочу, чтобы кто-нибудь помог мне решить эту проблему.

Подробнее здесь: https://stackoverflow.com/questions/792 ... service-pa
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «IOS»