Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fail to set source in iOS 18 #1845

Open
2 tasks done
rubamapps opened this issue Sep 28, 2024 · 4 comments
Open
2 tasks done

Fail to set source in iOS 18 #1845

rubamapps opened this issue Sep 28, 2024 · 4 comments
Labels

Comments

@rubamapps
Copy link

rubamapps commented Sep 28, 2024

Checklist

  • I read the troubleshooting guide before raising this issue
  • I made sure that the issue I am raising doesn't already exist

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
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

@rubamapps rubamapps added the bug label Sep 28, 2024
@sofienesalem
Copy link

Up, i have the same issue

@rubamapps
Copy link
Author

@rxlabz is there any fix schedule of this?

@cristian1980
Copy link

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

@jchirinosodio
Copy link

jchirinosodio commented Dec 13, 2024

Experiencing the same, the first times it works, but after setting the URL source on consecutive sounds, like 9 times usually it fails.

image

I also noticed this happening, after a second audio library that reproduces other types of sounds in my app failed, it had an exception and followed by that exception I got this one on the audioplayers library. -> In case it provides more feedback, it could be that both libraries interact on the native part.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants