bluefireteam / audioplayers

A Flutter package to play multiple audio files simultaneously (Android/iOS/web/Linux/Windows/macOS)
https://pub.dartlang.org/packages/audioplayers
MIT License
2.01k stars 845 forks source link

Fail to set source in iOS 18 #1845

Open rubamapps opened 1 month ago

rubamapps commented 1 month ago

Checklist

Current bug behaviour

I try to set the external source as I was working and this error appears in simulator with iOS 18. Then I opened again simulator with 17.5 version and works perfectly, so there is some issue with the new iOS version.

` import 'dart:async';

import 'package:audioplayers/audioplayers.dart' as ap; import 'package:dependencies/dependencies.dart';

class AudioPlayerWidget extends StatefulWidget { /// Path from where to play recorded audio final String source;

/// Callback when audio file should be removed /// Setting this to null hides the delete button final VoidCallback onDelete; final bool showDeleteIcon; final bool getFromUrl;

const AudioPlayerWidget({ super.key, required this.source, required this.onDelete, required this.showDeleteIcon, required this.getFromUrl, });

@override AudioPlayerState createState() => AudioPlayerState(); }

class AudioPlayerState extends State { static const double _controlSize = 56; static const double _deleteBtnSize = 24;

final _audioPlayer = ap.AudioPlayer()..setReleaseMode(ReleaseMode.stop); late StreamSubscription _playerStateChangedSubscription; late StreamSubscription<Duration?> _durationChangedSubscription; late StreamSubscription _positionChangedSubscription; Duration? _position; Duration? _duration;

@override void initState() { _playerStateChangedSubscription = _audioPlayer.onPlayerComplete.listen((state) async { await stop(); }); _positionChangedSubscription = _audioPlayer.onPositionChanged.listen( (position) => setState(() { _position = position; }), ); _durationChangedSubscription = _audioPlayer.onDurationChanged.listen( (duration) => setState(() { _duration = duration; }), );

_audioPlayer.setSource(_source);

super.initState();

}

@override void dispose() { _playerStateChangedSubscription.cancel(); _positionChangedSubscription.cancel(); _durationChangedSubscription.cancel(); _audioPlayer.dispose(); super.dispose(); }

@override Widget build(BuildContext context) { return LayoutBuilder( builder: (context, constraints) { return Column( mainAxisSize: MainAxisSize.min, children: [ Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ _buildControl(), _buildSlider(constraints.maxWidth), if (widget.showDeleteIcon) ...[ IconButton( icon: const Icon(Icons.delete, color: ThemeColors.indicatorRed, size: _deleteBtnSize), onPressed: () { if (_audioPlayer.state == ap.PlayerState.playing) { stop().then((value) => widget.onDelete()); } else { widget.onDelete(); } }, ), ], ], ), if (_duration != null) ...[ LabelWidget( alignment: Alignment.center, title: '${prettyDuration(_duration!)}'), ], ], ); }, ); }

String prettyDuration(Duration duration) { var seconds = (duration.inMilliseconds % (60 * 1000)) / 1000; if (duration.inMinutes != 0) { return '${duration.inMinutes}m ${seconds.truncate()}s'; } else { return '${seconds.truncate()}s'; } }

Widget _buildControl() { Icon icon; Color color;

if (_audioPlayer.state == ap.PlayerState.playing) {
  icon = const Icon(Icons.pause, color: ThemeColors.myDarkColor, size: 30);
  color = ThemeColors.myDarkColorTerciary;
} else {
  final theme = Theme.of(context);
  icon = const Icon(Icons.play_arrow,
      color: ThemeColors.myDarkColor, size: 30);
  color = ThemeColors.myDarkColorTerciary;
}

return ClipOval(
  child: Material(
    color: color,
    child: InkWell(
      child:
          SizedBox(width: _controlSize, height: _controlSize, child: icon),
      onTap: () {
        if (_audioPlayer.state == ap.PlayerState.playing) {
          pause();
        } else {
          play();
        }
      },
    ),
  ),
);

}

Widget _buildSlider(double widgetWidth) { bool canSetValue = false; final duration = _duration; final position = _position;

if (duration != null && position != null) {
  canSetValue = position.inMilliseconds > 0;
  canSetValue &= position.inMilliseconds < duration.inMilliseconds;
}

double width = widgetWidth - _controlSize - _deleteBtnSize;
if (widget.showDeleteIcon) {
  width -= _deleteBtnSize;
} else {
  width += _deleteBtnSize;
}

return SizedBox(
  width: width,
  child: Slider(
    activeColor: ThemeColors.myDarkColorTerciary,
    inactiveColor: widget.showDeleteIcon
        ? ThemeColors.myDarkColorSecondary
        : ThemeColors.myDarkColor,
    onChanged: (v) {
      if (duration != null) {
        final position = v * duration.inMilliseconds;
        _audioPlayer.seek(Duration(milliseconds: position.round()));
      }
    },
    value: canSetValue && duration != null && position != null
        ? position.inMilliseconds / duration.inMilliseconds
        : 0.0,
  ),
);

}

Future play() => _audioPlayer.play(_source);

Future pause() async { await _audioPlayer.pause(); setState(() {}); }

Future stop() async { await _audioPlayer.stop(); setState(() {}); }

Source get _source => widget.getFromUrl ? ap.UrlSource(widget.source) : ap.DeviceFileSource(widget.source); } `

PlatformException(DarwinAudioError, Failed to set source. For troubleshooting, see https://github.com/bluefireteam/audioplayers/blob/main/troubleshooting.md, AVPlayerItem.Status.failed on setSourceUrl: Unknown error, null)<…> 3 [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(DarwinAudioError, Failed to set source. For troubleshooting, see https://github.com/bluefireteam/audioplayers/blob/main/troubleshooting.md, AVPlayerItem.Status.failed on setSourceUrl: Unknown error, null) import 'dart:async';

Expected behaviour

It should load the external source.

Steps to reproduce

  1. Execute flutter run on the code sample
  2. ...
  3. ...

Code sample

Code sample ```dart void main() { } ```

Affected platforms

iOS

Platform details

No response

AudioPlayers Version

6.1.0

Build mode

No response

Audio Files/URLs/Sources

No response

Screenshots

No response

Logs

my relevant logs
Full Logs ``` my full logs or a link to a gist ``` Flutter doctor: ``` Output of: flutter doctor -v ```

Related issues / more information

No response

Working on PR

no way

sofienesalem commented 1 month ago

Up, i have the same issue

rubamapps commented 1 month ago

@rxlabz is there any fix schedule of this?

cristian1980 commented 1 month ago

Can someone add this f15b414135039b72760a908b95c01aa8c9da6422 so we don't get 'Unknown error'