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

PlatformException(DarwinAudioError, AVPlayerItem.Status.failed on setSourceUrl, #1546

Closed
2 tasks done
lurongshuang opened this issue Jun 15, 2023 · 29 comments · Fixed by #1625
Closed
2 tasks done

PlatformException(DarwinAudioError, AVPlayerItem.Status.failed on setSourceUrl, #1546

lurongshuang opened this issue Jun 15, 2023 · 29 comments · Fixed by #1625
Labels
bug platform-ios Affects the ios platform waiting for report Wait for the author to respond to the conversation

Comments

@lurongshuang
Copy link

lurongshuang commented Jun 15, 2023

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

^[[31mAudioPlayers Exception: AudioPlayerException(
DeviceFileSource(path: /var/mobile/Containers/Data/Application/05BFE1FD-0371-4C27-A279-38645C04E5C3/Library/Caches/recording.aac),
PlatformException(DarwinAudioError, AVPlayerItem.Status.failed on setSourceUrl, null, null)<…>
[VERBOSE-2:dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(DarwinAudioError, AVPlayerItem.Status.failed on setSourceUrl, null, null)

Expected behaviour

await _player.setSourceDeviceFile(fileUrl);
_player.play(source);

Steps to reproduce

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

Code sample

  void playAudioWithFile(String fileUrl,
      {Function? onPlaying, Function? onPlayCompleted}) async{
    this.onPlaying = onPlaying;
    this.onPlayCompleted = onPlayCompleted;
    DeviceFileSource source = DeviceFileSource(fileUrl);

    await _player.setSourceDeviceFile(fileUrl);
    _player.play(source);
  }

Affected platforms

iOS

Platform details

Android 正常
ios 报错

AudioPlayers Version

audioplayers: ^4.1.0

Build mode

debug

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

@isaanyoha
Copy link

isaanyoha commented Jun 18, 2023

Same here. Did you resolve this? This happened to me in iOS 16.0 (physical device) & iOS 16.2 (Simulator)

@lurongshuang
Copy link
Author

Codec _codec = Codec.defaultCodec;
String _mPath = 'tau_file';

@isaanyoha
Copy link

isaanyoha commented Jun 19, 2023

Codec _codec = Codec.defaultCodec; String _mPath = 'tau_file';

Thanks for reply. Meanwhile, kindly give me details. Where do I write this?

-BELOW IS MY CODE-

final audioPlayer = AudioPlayer();
try {
await audioPlayer.play(AssetSource("sounds/file1.aac"));
}catch(e){
print("could not play sound from local");
}

-ERROR BELOW-

flutter: ^[[31mAudioPlayers Exception: AudioPlayerException(
AssetSource(path: sounds/file1.aac),
PlatformException(DarwinAudioError, AVPlayerItem.Status.failed on setSourceUrl, null, null)<…>
flutter: soundNotification error -> PlatformException(DarwinAudioError, AVPlayerItem.Status.failed on setSourceUrl, null, null)

@simpleease
Copy link

same here. Both on simulator or device, iOS 16.1 & iOS 16.4.
For remote Url, the same error:
PlatformException(DarwinAudioError, AVPlayerItem.Status.failed on setSourceUrl, null, null)<…>
flutter: soundNotification error -> PlatformException(DarwinAudioError, AVPlayerItem.Status.failed on setSourceUrl, null, null)

=======
test url below(token may expired) :
http://rongcloud-audio.ronghub.com/audio_amr__RC-2023-06-23_105_1687459422837.aac?e=1703011423&token=livk5rb3__JZjCtEiMxXpQ8QscLxbNLehwhHySnX:uaD5J8RHAALUPty1NloOyk0HhIk=

=======
but when the above url downloaded to local and saved as ".m4a" extension, it works, without error.

@Mamong
Copy link
Contributor

Mamong commented Jun 25, 2023

I think it's apple's bug. audioplayers can do nothing. as a workaround, you can download it before playing.

@SwiftSpotter
Copy link

I am facing the same issue

@fullflash
Copy link

fullflash commented Jul 5, 2023

yes looks like this plugin has issues playing asset files
happens with asset and remote files. was working properly.

@karlssonlui
Copy link

I faced this problem too with the following situation, and I think this is because ios (or macos as well) has its own codec for audio, which android aacLc may not be equal to apple aacLc (Please correct me if I make a wrong statement). Somehow I changed the encoder method from aacLc to pcm16bit for ios platform (record package mentioned that pcm8bit has been removed in 5.0.0-beta.2, thats why i use pcm16bit). Hope this idea helps.

References
platform: ios
audio source: record: ^4.4.4
audio player: audioplayers: ^4.0.1

Original code

final Record _recorder = Record();
AudioEncoder encoder = AudioEncoder.aacLc;
await _recorder.start(path: path, encoder: encoder);

New code

final Record _recorder = Record();
AudioEncoder encoder = Platform.isIOS ? AudioEncoder.pcm16bit : AudioEncoder.aacLc;
await _recorder.start(path: path, encoder: encoder);

@SwiftSpotter
Copy link

SwiftSpotter commented Aug 2, 2023 via email

@karlssonlui
Copy link

For my case, it seems that audioplayers cannot decode the audio bytes in the audio files, may be you can find another audio file from different source and test your code first, if the different source audio file works, you have to convert your audio files to a usable one

@008v
Copy link

008v commented Aug 23, 2023

edit your Info.plist , add these lines:

<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSAllowsArbitraryLoads</key>
		<true/>
	</dict>

it works for me

@nomagicisreal
Copy link

nomagicisreal commented Aug 26, 2023

i solved by renaming path without any space

@maojiu-bb
Copy link

@petiibhuzah

This comment was marked as outdated.

@Gustl22
Copy link
Collaborator

Gustl22 commented Sep 1, 2023

if (Platform.isIOS) {

@petiibhuzah For local files (here: downloaded files), always use the DeviceFileSource. No need to make an exception for Android (or any other platform) to use UrlSource there...it's not meant to use for local files.

@haihv433
Copy link

haihv433 commented Sep 12, 2023

any work around? I'm facing this in fresh new project (Simulate IP14 but was okay on Web version)

@Gustl22
Copy link
Collaborator

Gustl22 commented Sep 26, 2023

@lurongshuang it's most likely #1494. And further your code doesn't really make sense:

Plz call either:

DeviceFileSource source = DeviceFileSource(fileUrl);
await _player.setSourceDeviceFile(fileUrl);
await _player.resume();

or

DeviceFileSource source = DeviceFileSource(fileUrl);
await _player.play(source);

@Gustl22 Gustl22 added platform-ios Affects the ios platform waiting for report Wait for the author to respond to the conversation labels Sep 26, 2023
Gustl22 added a commit that referenced this issue Sep 29, 2023
# Description

- feat: Improved error description for unsupported file formats
- fix: Handle white space and special characters in URL and Assets (Web
& Darwin)
- test: Test files without file extension (not playable Darwin)

## Related Issues

Closes #1494
Closes #748
Closes #972
Closes #1546

---------

Co-authored-by: Lukas Klingsbo <[email protected]>
Gustl22 added a commit that referenced this issue Sep 29, 2023
# Description

- feat: Improved error description for unsupported file formats
- fix: Handle white space and special characters in URL and Assets (Web
& Darwin)
- test: Test files without file extension (not playable Darwin)

## Related Issues

Closes #1494
Closes #748
Closes #972
Closes #1546

---------

Co-authored-by: Lukas Klingsbo <[email protected]>
(cherry picked from commit a4d8442)
@Mamong
Copy link
Contributor

Mamong commented Oct 1, 2023

you can test this url:https://dict.youdao.com/dictvoice?audio=hobby&type=1

@Mamong
Copy link
Contributor

Mamong commented Oct 2, 2023

@Gustl22 Thanks,after some research,I think avplayer can play a remote audio file through a url without a file extension correctly. In my case, it fails only because it has wrong "content-type", while this link can play successfully: https://dict.youdao.com/dictvoice?audio=hobby&type=2 . it's an mp3 file.

@Mamong
Copy link
Contributor

Mamong commented Oct 3, 2023

@Gustl22 this repo based on AVPlayer and AVAssetResourceLoaderDelegate may optimise the way playing a remote audio:
SZAVPlayer

Gustl22 added a commit that referenced this issue Nov 14, 2023
# Description

- feat: Improved error description for unsupported file formats
- fix: Handle white space and special characters in URL and Assets (Web
& Darwin)
- test: Test files without file extension (not playable Darwin)

## Related Issues

Closes #1494
Closes #748
Closes #972
Closes #1546

---------

Co-authored-by: Lukas Klingsbo <[email protected]>
@Gustl22
Copy link
Collaborator

Gustl22 commented Nov 20, 2023

@Mamong We trying to avoid third party implementations, and rather fix the missing contentType ourselfes. It is definitely not that hard, it just needs to be done. I have no Apple environment to properly develop and test, and I also don't have the time at the moment. Feel free to help us out. Let's continue discussion in #803.

@5Gears0Chill
Copy link

So i stumbled across this error. I know this issue is closed, but this seemed to help.

First i had the issue in just_audio, where flutter ios would fail.

I thought to myself, weird It works perfectly on android but iOS just dies.

Migrated to audioplayers and got hit with this Darwin error.

I said this must be an issue with iOS and the URL im trying to get the file from.

For context we are using Strapi as our CMS.

So i built this simple method.

import 'dart:io';
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';

  Future<File?> downloadMp3(String url) async {
    Dio dio = Dio();
    Directory tempDir = await getTemporaryDirectory();
    String fileName = url.split('/').last; // Extract the file name from the URL
    String savePath = '${tempDir.path}/$fileName';

    // Check if the file already exists
    File file = File(savePath);
    if (await file.exists()) {
      // File already exists, no need to download again
      return file;
    }

    try {
      EasyLoading.show(
        status: 'Downloading...',
      );
      await dio.download(
        url,
        savePath,
        onReceiveProgress: (received, total) {
          if (total != -1) {
            if (kDebugMode) {
              print('${(received / total * 100).toStringAsFixed(0)}%');
            }
          }
        },
      );
    } catch (e) {
      if (kDebugMode) {
        print('Error downloading file: $e');
      }
      EasyLoading.showError('Failed to download file');
      return null; // Return null to indicate failure
    } finally {
      EasyLoading.dismiss();
    }

    return File(savePath);
  }

Then for my playAudio functionality

playAudio() async {
    try {
      if (isPlaying) {
        await player.pause();
      } else {
        await player.stop();
        if (Platform.isAndroid) {
          await player.play(UrlSource(widget.url));
        } else {
          var file = await downloadMp3(widget.url);
          if (file != null) {
            await player.play(DeviceFileSource(file.path));
          }
        }
      }
    } catch (e) {
      if (kDebugMode) {
        print(e);
      }
    }
  }

And it works perfectly now.

@narakai
Copy link

narakai commented Dec 27, 2023

So i stumbled across this error. I know this issue is closed, but this seemed to help.

First i had the issue in just_audio, where flutter ios would fail.

I thought to myself, weird It works perfectly on android but iOS just dies.

Migrated to audioplayers and got hit with this Darwin error.

I said this must be an issue with iOS and the URL im trying to get the file from.

For context we are using Strapi as our CMS.

So i built this simple method.

import 'dart:io';
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';

  Future<File?> downloadMp3(String url) async {
    Dio dio = Dio();
    Directory tempDir = await getTemporaryDirectory();
    String fileName = url.split('/').last; // Extract the file name from the URL
    String savePath = '${tempDir.path}/$fileName';

    // Check if the file already exists
    File file = File(savePath);
    if (await file.exists()) {
      // File already exists, no need to download again
      return file;
    }

    try {
      EasyLoading.show(
        status: 'Downloading...',
      );
      await dio.download(
        url,
        savePath,
        onReceiveProgress: (received, total) {
          if (total != -1) {
            if (kDebugMode) {
              print('${(received / total * 100).toStringAsFixed(0)}%');
            }
          }
        },
      );
    } catch (e) {
      if (kDebugMode) {
        print('Error downloading file: $e');
      }
      EasyLoading.showError('Failed to download file');
      return null; // Return null to indicate failure
    } finally {
      EasyLoading.dismiss();
    }

    return File(savePath);
  }

Then for my playAudio functionality

playAudio() async {
    try {
      if (isPlaying) {
        await player.pause();
      } else {
        await player.stop();
        if (Platform.isAndroid) {
          await player.play(UrlSource(widget.url));
        } else {
          var file = await downloadMp3(widget.url);
          if (file != null) {
            await player.play(DeviceFileSource(file.path));
          }
        }
      }
    } catch (e) {
      if (kDebugMode) {
        print(e);
      }
    }
  }

And it works perfectly now.

Hi, I met same issue, first I used just_audio, but flutter ios keep failing. Now I use audioplayers to try to get ios work.
I tried to download first and then play mp3, but still it says: 'PlatformException(DarwinAudioError, Failed to set source'.

My code is like:

// Method to dynamically set a new MediaItem.
Future setMediaItem(MediaItem item) async {
_item = item;
mediaItem.add(_item);
// Load the player with the new media item.
DeviceFileSource source = DeviceFileSource(_item.id);
await _player.setSourceDeviceFile(_item.id);
await _player.play(source);
}

Can you give me some advice, thanks.

@vaimikpatel2908
Copy link

vaimikpatel2908 commented Jan 14, 2024

My code is as follows:

Future<void> startPlayer(String filepath) async {
    try {
 // For ex, filepath is getApplicationDocumentDirectory().path+"/file.aac"
      final DeviceFileSource source = DeviceFileSource(filepath); 
     
        await _player?.play(source);
        } catch (e) {
      throw SoundPlayerException(e.toString());
    }
  }

But it still throws the PlatformException(DarwinAudioError, AVPlayerItem.Status.failed on setSourceUrl, Failed to set source. For troubleshooting, see "
+ "https://github.com/bluefireteam/audioplayers/blob/main/troubleshooting.md). It works smoothly on Android. Not sure what is the exact issue. the same code was working fine earlier. I tried Flutter_soundas well. it is not able to play the audio file as well.

I have also copied the code from the demo/examples and tried to play the same file as well but no luck with both plugins.

If anyone has idea, please guide me. I am totally clueless.

@Gustl22
Copy link
Collaborator

Gustl22 commented Mar 15, 2024

Some of the problems are probably fixed via #1763

Plz open new issues on problems after this fix, to better separate different causes for the issue.

@5Gears0Chill
Copy link

So i stumbled across this error. I know this issue is closed, but this seemed to help.
First i had the issue in just_audio, where flutter ios would fail.
I thought to myself, weird It works perfectly on android but iOS just dies.
Migrated to audioplayers and got hit with this Darwin error.
I said this must be an issue with iOS and the URL im trying to get the file from.
For context we are using Strapi as our CMS.
So i built this simple method.

import 'dart:io';
import 'package:dio/dio.dart';
import 'package:path_provider/path_provider.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';

  Future<File?> downloadMp3(String url) async {
    Dio dio = Dio();
    Directory tempDir = await getTemporaryDirectory();
    String fileName = url.split('/').last; // Extract the file name from the URL
    String savePath = '${tempDir.path}/$fileName';

    // Check if the file already exists
    File file = File(savePath);
    if (await file.exists()) {
      // File already exists, no need to download again
      return file;
    }

    try {
      EasyLoading.show(
        status: 'Downloading...',
      );
      await dio.download(
        url,
        savePath,
        onReceiveProgress: (received, total) {
          if (total != -1) {
            if (kDebugMode) {
              print('${(received / total * 100).toStringAsFixed(0)}%');
            }
          }
        },
      );
    } catch (e) {
      if (kDebugMode) {
        print('Error downloading file: $e');
      }
      EasyLoading.showError('Failed to download file');
      return null; // Return null to indicate failure
    } finally {
      EasyLoading.dismiss();
    }

    return File(savePath);
  }

Then for my playAudio functionality

playAudio() async {
    try {
      if (isPlaying) {
        await player.pause();
      } else {
        await player.stop();
        if (Platform.isAndroid) {
          await player.play(UrlSource(widget.url));
        } else {
          var file = await downloadMp3(widget.url);
          if (file != null) {
            await player.play(DeviceFileSource(file.path));
          }
        }
      }
    } catch (e) {
      if (kDebugMode) {
        print(e);
      }
    }
  }

And it works perfectly now.

Hi, I met same issue, first I used just_audio, but flutter ios keep failing. Now I use audioplayers to try to get ios work. I tried to download first and then play mp3, but still it says: 'PlatformException(DarwinAudioError, Failed to set source'.

My code is like:

// Method to dynamically set a new MediaItem. Future setMediaItem(MediaItem item) async { _item = item; mediaItem.add(_item); // Load the player with the new media item. DeviceFileSource source = DeviceFileSource(_item.id); await _player.setSourceDeviceFile(_item.id); await _player.play(source); }

Can you give me some advice, thanks.

It seems you are using item.id ?
Maybe that is your issue?

@minnatranscriber
Copy link

do we have any solution for this?

@wishwelloklu
Copy link

@lurongshuang it's most likely #1494. And further your code doesn't really make sense:

Plz call either:

DeviceFileSource source = DeviceFileSource(fileUrl);
await _player.setSourceDeviceFile(fileUrl);
await _player.resume();

or

DeviceFileSource source = DeviceFileSource(fileUrl);
await _player.play(source);

This worked for me. Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug platform-ios Affects the ios platform waiting for report Wait for the author to respond to the conversation
Projects
None yet
Development

Successfully merging a pull request may close this issue.