Flutter中的音频播放器插件 - 无法加载资产

3
我正在尝试在Flutter中创建一个闹钟,一定时间后会发出闹钟声。在Flutter中似乎这比说起来容易得多!
我尝试使用audioplayer插件来实现这一点。使用playLocal函数,其中资产从rootbundle加载到应用程序目录,然后播放。
根据audioplayer github回复中的一个答案,这是应该做到这一点的代码:
class SoundManager {
 AudioPlayer audioPlayer = new AudioPlayer();

Future playLocal(localFileName) async {
  final dir = await getApplicationDocumentsDirectory();
  final file = new File("${dir.path}/$localFileName");
  if (!(await file.exists())) {
    final soundData = await rootBundle.load("assets/$localFileName");
    final bytes = soundData.buffer.asUint8List();
    await file.writeAsBytes(bytes, flush: true);
  }
  await audioPlayer.play(file.path, isLocal: true);
 }
}

我一直收到一个错误:"无法加载资源"。该资源(mp3/wav文件)显然在文件夹中,并且该文件夹已正确包含在pubspec.yaml文件中(来自此文件夹的其他图像资源正在正确加载,因此指定文件夹本身不是问题所在)。


你试过这个吗:https://github.com/rxlabz/audioplayer/issues/5 - Rashiduzzaman Khan
是的,这就是我在上面提到的问题中引用的那个线程的答案(https://github.com/rxlabz/audioplayer/issues/5#issuecomment-388699508)。 - Suparna Gharpure
2个回答

8

您可以使用另一个音频库 https://pub.dev/packages/audioplayers

AudioCache 文档。 https://github.com/luanpotter/audioplayers/blob/master/doc/audio_cache.md

简单示例:

import 'package:audioplayers/audio_cache.dart';
AudioCache player = AudioCache();
player.play('sounds/test_sound.m4a');

在这个例子中,我的资产文件夹看起来像这样:assets/sounds/test_sound.m4a。
这个库会将音频作为本地文件缓存,然后播放音频。
提示:如果你想从本地文件播放音乐,可以使用AudioPlayer()。
我有一个带有监听器的例子,在播放完成时会调用onPlayCompletion。
AudioPlayer _advancedPlayer = AudioPlayer();
Stream<void> playFromLocal(int unitId, int id) {
var link = '/media/$unitId/words/$id.m4a';
_advancedPlayer.stop();
_advancedPlayer.release();
_advancedPlayer = AudioPlayer();


_advancedPlayer.play(Const.basePath + link, isLocal: true);
return _advancedPlayer.onPlayerCompletion;

}


如果我想从getExternalStorageDirectory加载音频文件怎么办? - FilipeOS
@FilipeOS 我更新了我的答案,以便从本地文件播放音频。 - Anton Molchan
@Naeem 是的,我们在两个平台上都使用它。 - Anton Molchan

0

这对iOS和Android都适用良好。注意:如果本地没有可用的文件,则从URL下载。

AudioProvider audioProvider;
_playSound() async {
    audioProvider = AudioProvider("http:...");
    var soundToPlay = "myLocalSound";
    String localUrl = await audioProvider.load(soundToPlay);
    SoundController.play(localUrl);
  }
}

audio_provider.dart

import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:path_provider/path_provider.dart';
import 'package:http/http.dart';

typedef void OnError(Exception exception);

class AudioProvider {
  String url;
  AudioProvider(String url) {
    this.url = url;
  }

  Future<Uint8List> _loadFileBytes(String url, {OnError onError}) async {
    Uint8List bytes;
    try {
      bytes = await readBytes(url);
    } on ClientException {
      rethrow;
    }
    return bytes;
  }

  Future<String> load(fileName) async {
    final dir = await getApplicationDocumentsDirectory();
    final file = new File('${dir.path}/$fileName');
    if (await file.exists()) {print("file exists");
      return file.path;
    }
    var filePath = url +fileName;
    final bytes = await _loadFileBytes(filePath,
        onError: (Exception exception) =>
            print('audio_provider.load => exception ${exception}'));
    await file.writeAsBytes(bytes);
    if (await file.exists()) {
      return file.path;
    }
    return '';
  }
}

soundController.dart

import 'package:flutter/foundation.dart';
import 'package:audioplayers/audio_cache.dart';
import 'package:audioplayers/audioplayers.dart';
import 'dart:io' show Platform;


void audioPlayerHandler(AudioPlayerState value) => null;

class SoundController {

  static AudioPlayer audioPlayer = AudioPlayer(mode: PlayerMode.LOW_LATENCY);
  static AudioCache audioCache = AudioCache(prefix: "assets/audio/", fixedPlayer: audioPlayer);

  static void play(String sound) {

    if (!kIsWeb && Platform.isIOS) {
      audioPlayer.monitorNotificationStateChanges(audioPlayerHandler);
    }
    audioPlayer.play(sound, isLocal: true);
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接