如何获取音频文件的长度而不在 Flutter/Dart 中播放

Posted

技术标签:

【中文标题】如何获取音频文件的长度而不在 Flutter/Dart 中播放【英文标题】:How to get length of audio file without playing it in Flutter/Dart 【发布时间】:2020-03-18 19:27:14 【问题描述】:

我正在尝试在我的 Flutter 应用程序中显示音频文件的长度。我已经使用了 flutter_sound 和 audioplayers 插件,但我不确定如何在不播放音频文件的情况下获取音频文件的长度并获取持续时间(我想在列表中显示每个音频文件的长度,以便用户知道它有多长打之前)。除了在其中一个插件中使用播放音频文件的持续时间之外,我无法在网上找到任何地方显示如何在 dart 中获取音频文件长度。有人知道如何在飞镖中获取音频文件的长度吗?

【问题讨论】:

【参考方案1】:

这是一个迟到的答案,但如果您仍然想知道如何做到这一点,有一个音频库just_audio

final player = AudioPlayer();
var duration = await player.setUrl('file.mp3');

适用于安卓和ios,支持本地文件和下载网址。

【讨论】:

我之所以来到这里,是因为 just_audio 在 iOS 上给了我错误的持续时间。【参考方案2】:

如果您仍想使用AudioPlayers 和AudioCache,请在实际播放之前加载文件。否则在执行Slider的除法时会报错。

使用 AudioCache 预加载文件,这将返回文件的未来。将其与 然后阻止并使用其中包含路径的传递文件。在音频播放器上设置 url 并返回。将这个链接到另一个 then 块中,然后从 getDuration 调用返回未来。现在在您未来的构建器中使用它,当快照为空时使用旋转加载器,当快照有值时使用您的音乐播放器。

考虑这个例子:

Future<int> loadFile() 
return audioCache.loadFile(widget.fileName)
    .then((value) 
      print(value);
      cachedFilePath = value.path;
      return audioPlayer.setUrl(value.path, isLocal: true);
    )
    .then((value) => audioPlayer.getDuration());

我在 initState 中调用了这个函数以避免多次调用未来并将未来存储在一个 Future 变量中。

  @override
  void initState() 
    print("init");
    super.initState();

    audioPlayer = AudioPlayer();

    audioCache.init();

    audioPlayer.onDurationChanged.listen((d) => setState(() => _duration = d));

    audioPlayer.onAudioPositionChanged.listen((p) => setState(() => _position = p));

    audioPlayer.onPlayerCompletion.listen((event) 
      setState(() 
        _position = Duration(seconds: 0);
        issongplaying = false;
      );
    );

    _loadFile = loadFile();
  

接下来,我在未来的构建器中使用了_loadFile 变量。在未来的构建器中,我还添加了一个加载器。

return FutureBuilder(
  future: _loadFile,
  builder: (context, snapshot) 
    if (snapshot.data == null)
      return // Implement your loading spinning widget here
    else
      return // Implement your widget here

【讨论】:

【参考方案3】:

迟到的答案,但也许它仍然对某人有所帮助。

你可以像这样尝试flutter_ffmpeg:

import 'package:flutter_ffmpeg/flutter_ffmpeg.dart';
import 'package:flutter_ffmpeg/log_level.dart';

final FlutterFFprobe _flutterFFprobe = new FlutterFFprobe();

Future<int> lenghOfAudio(File audio)async
    Map info = await _flutterFFprobe.getMediaInformation(audio.path);
// the given duration is in milliseconds, assuming you want to have seconds I divide by 1000
    int seconds = (info['duration']/1000).round();
    print('DURATION: $seconds.toString()');
    return seconds;

当然,对于这么小的任务,ffmpeg 是一个非常大的库,但它避免播放我也不喜欢的音频文件。

【讨论】:

【参考方案4】:

这对我有用:

    // We need to play the file in order to get its duration.
    _player = await AudioCache().play(filePath);

    _player.onDurationChanged.listen((Duration duration) 
      // Now that we have the duration, stop the player.
      _player.stop();
      _durationMs = duration.inMilliseconds;
    );

【讨论】:

【参考方案5】:

首先在 pubspec.yaml 中添加“just_audio:”,并将其导入所需的屏幕文件中。 现在您可以根据需要调整代码:

// 
final player = AudioPlayer();
//

void durationHandler(String path) async 
    print("Duration Handler Started"); //---------------------------------->
//
    var duration = await player.setFilePath(path);
    print(duration);
    print("Duration Handler Ended"); //---------------------------------->
  

 onTap: () 
                //ON TAP ON A MUSIC----------------------------------------->
                durationHandler('path/of/file/in/device');
              ,
 */

【讨论】:

【参考方案6】:

通过此方法,您将获得此格式的 Duration Max duration: 0:06:12.715000

  AudioPlayer audioPlayer = AudioPlayer();

  audioPlayer.onDurationChanged.listen((Duration d) 
    print('Max duration: $d');
  );

【讨论】:

【参考方案7】:

我正在使用下面的代码来获取音频文件的持续时间。 audioplayers

第一次通话

AudioPlayer audioPlayer = AudioPlayer();   
audioPlayer.setUrl(audioFilePath, isLocal: true);

它会触发音频播放器的 onDurationChanged 监听函数,我们将获得不播放音频文件的最大持续时间。

audioPlayer.onDurationChanged.listen((Duration d) 
  print('max duration: $d.inSeconds');

);

【讨论】:

【参考方案8】:

使用这个库audioplayers,

像这样获取持续时间事件

此事件返回文件可用时的持续时间(可能需要一段时间,因为它正在下载或缓冲)。

  player.onDurationChanged.listen((Duration d) 
    print('Max duration: $d');
    setState(() => duration = d);
  );

【讨论】:

这是我正在使用的插件,但是播放器的持续时间状态不会改变以获得持续时间,直到播放器正在播放(我想要一个玩家列表并显示持续时间他们的每个音频文件)。我是否必须启动并快速停止每个文件才能在更改期间加载它?

以上是关于如何获取音频文件的长度而不在 Flutter/Dart 中播放的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 sox 获取所有音频的音频长度?

如何在Objective c中获取音频文件的某些部分

如何确定与 AVAudioPlayer 关联的音频文件的长度

无法在网页上获取 m4a 音频文件的长度

如何播放音频样本而不将其写入文件?

PHP - 获取音频长度