【问题标题】:AudioPlayers does not work on iOS | Flutter pluginAudioPlayers 不适用于 iOS |颤振插件
【发布时间】:2021-02-02 08:46:35
【问题描述】:

我正在创建一个 Flutter 插件。目前,代码:

  1. 将字符串合成为音频文件
  2. 获取文件路径
  3. 使用audioplayers 播放音频文件

当我在 Android 中运行该应用程序时,它可以完美运行。然而,当我在 iOS 上运行它时,它不会(假设相关权限/限制)

await flutterTts
        .synthesizeToFile(
            "This is my first audio synthesizer in Flutter", audioFileName)
        .then((success) => {
              if (success == 1)
                {
                  print('Successfully synthesized!!'),

                  // Gets the path to the generated file depending on the platform
                  pathFile =
                      Platform.isAndroid ? pathToFileAndroid : pathToFileIos,
                  pathFile
                      .then((pathToAudioFile) => {
                            print('Path to file: ' + pathToAudioFile),
                            // Speakers/earpiece
                            // int result = await player.earpieceOrSpeakersToggle();
                            // Sets the path to the file
                            audioPlayer.setUrl(pathToAudioFile),
                            audioPlayer.setVolume(1.0),
                            // Gets the duration of the audio file to be reproduced
                            // Plays the audio file
                            playLocal(audioPlayer, pathToAudioFile),
                          }) // pathFile
                      .catchError((e) {
                    print('Error: Unable to get the path to the audio file');
                  }),
                }, // success
            }) //synthesizeToFile
        .catchError((e) {
      print('Error during the synthesisation: $e');
    });
  }




/// Gets the path to the file to be accessed (iOS)
  static Future<String> get pathToFileIos async {
    Directory appDocDir = await getApplicationDocumentsDirectory();
    String appDocPath = appDocDir.path;
    print('appDocPath: $appDocPath');
    return '$appDocPath/$audioFileName';
  }

我实现了audioPlayer.onDurationChanged.listen 来确认文件的路径是正确的(它实际上得到了文件的持续时间)。然而,该文件并未播放。

我正在使用模拟器测试应用程序,这是存放文件的路径

/localPaty/Devices/deviceID/data/Containers/Data/Application/appID/Documents/temp_audio_cue.caf

我阅读了有关此主题的不同问题,但没有找到适合我的案例的解决方案

我试过了:

按照文档的建议编辑传输安全

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

使用AudioCache (question)

有人有其他建议吗?我需要将文件移动到我的本地资产并使用AudioCache 来重现文件吗?

更新

我也尝试添加标志isLocal

  playLocal() async {
    int result = await audioPlayer.play(localPath, isLocal: true);
  }

根据documentation是需要的原因

isLocal 标志是必需的,因为 iOS 和 macOS 对此有所不同

它返回1,所以我猜这意味着成功,但声音仍然没有触发。可能是模拟器失败了?

"iOS => call startHeadlessService, playerId ID"
"iOS => call setUrl, playerId ID"
"iOS => call setVolume, playerId ID"
"iOS => call play, playerId ID"
2021-02-03 11:59:33.149925+0100 Runner[61496:850044] flutter: Played successfully?: 1

我还测试了以错误的路径调用playLocal()。它不断返回1,但之后显示以下错误:

FigFileForkOpenMainByCFURL 发出信号 err=2 (errno)(打开失败)

尽管如此,使用正确的localPath 调用方法不会触发错误,所以我认为它应该可以正确播放。

注意

如果我不打电话给playLocal(),而是打电话给flutter_tts.speak('test'),它会起作用。因此,错误应该与audioplayers有关。

我使用的版本是flutter_tts ^2.1.0audioplayers: ^0.17.3

【问题讨论】:

  • 您好,我有一个问题,我必须在 Flutter 应用程序中添加这些内容。 NSAppTransportSecurityNSAllowsArbitraryLoads

标签: ios flutter file audio


【解决方案1】:

最后,我意识到问题与AVAudioSession 及其会话管理有关。 flutter_ttsaudioplayers 这两个库都使用了它,因此它们可以覆盖它。

我不得不将方法更改为以下内容:

 /// Synthesises the current audio cue into an audio file
  static Future<void> synthesiseStringToAudioFile() async {
    int synthesized = await flutterTts.synthesizeToFile(
        "This is my first audio synthesizer in Flutter", audioFileName);
    if (synthesized == 1) {
      String pathFile =
          await (Platform.isAndroid ? pathToFileAndroid : pathToFileIos);
      print('Path to file: ' + pathFile);
      playAudioFile(pathFile);
    } else {
      print('Error during the synthesisation');
    }
  }

开始在iOS 中触发一些音频。尽管如此,通知中仍然存在一些问题,但我认为答案已经得到解答。

【讨论】:

    【解决方案2】:

    当您使用audio players 播放声音并使用flutter_tts 说词时,它会使flutter_tts 在iOS 上功能失调

    因此,只有一个包可以工作,但是一旦同时使用两个包,tts 会在一段时间后停止工作。有时会持续更长时间,但有时会立即停止。

    实际上,这是由于 iOS 端的冲突造成的。

    假设它可以在 Android 上运行,这意味着您的代码应该没有问题。

    必须找到另一种选择。

    【讨论】:

      【解决方案3】:

      今天我已经解决了这个问题。我正在使用来自 URL 的音频,我正在使用这一行

        var res = await audioPlayer.play(url, isLocal: true);
      

      我必须在我的代码中使用下面这一行

        var res = await audioPlayer.play(url, isLocal: false);
      

      isLocal 代表您的文件是否存储在本地。如果文件以 URL 的形式远程存储,则设置为isLocal:false

      希望它能解决你的问题。

      【讨论】:

        【解决方案4】:

        使用 IOS 时使用 play() 方法而不是 playBytes()。整数结果=0; if(Platform.isIOS){ result = await player.play("Audio url",isLocal: false); }

        【讨论】:

          猜你喜欢
          • 2019-06-21
          • 2021-08-07
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-19
          • 1970-01-01
          • 2021-10-06
          • 2021-08-15
          相关资源
          最近更新 更多