Kyle B.
Kyle B.

Reputation: 439

How to get length of audio file without playing it in Flutter/Dart

I'm trying to display the length of audio files in my Flutter application. I've used both the flutter_sound and audioplayers plugins but I'm not sure how to get the length of the audio file without playing it and getting the duration (which I want to display the length of each audio file in a list so users know how long it is before playing). I haven't been able to find anywhere online that shows how to get the audio file length in dart except from using the duration of the playing audio file in one of those plugins. Anyone know how to get audio file length's in dart?

Upvotes: 13

Views: 24885

Answers (13)

final player = AudioPlayer();

  Future<Duration> getDuration(String path) async {
    print('kkkkkkkkkkkk $path');
    await player.setSourceUrl(path);
    var duration = await player.getDuration();
    setState(() {});
    print('kkkkkkkkkkkk $duration');

    return duration ?? const Duration();
  }

  Duration sizeOfAudio = const Duration();
  @override
  void initState() {
    getDuration(widget.audio.link ?? '').then((value) {
      setState(() {
        sizeOfAudio = value;
      });
    });

    super.initState();
  }

Upvotes: 0

novas1r1
novas1r1

Reputation: 1934

You can use the flutter_soloud package to do this:

// initialize once
final soloud = SoLoud.instance;
await soloud.init();

// choose source
final source = await soLoud.loadFile(file.path);

// get duration
final duration = soLoud.getLength(source);

// dispose source
await soLoud.disposeSource(source);

Upvotes: 1

Việt Cao
Việt Cao

Reputation: 11

Use Future method (assets file):

Future<String> getDurationFollowLink(String linkPath) async {   
    AudioPlayer playerHere = AudioPlayer();    
    await playerHere.setSource(AssetSource(linkPath));    
    Duration? duration; 
    await playerHere.getDuration().then((value) async { 
     duration = value; 
    });    
    return duration.toString().split('.').first;

Then get it by FutureBulder in UI:

FutureBuilder<String?>(
future: getDurationFollowLink(linkPath),
builder: (context, value) {
 return Text(value.data.toString());
 },
),

Upvotes: 0

Keith Bacalso
Keith Bacalso

Reputation: 1

if your Duration initally starts at zero, but only gets the total Duration of the song when played then you need to use the audioPlayer.setSource() :)

Upvotes: 0

IcyIcicle
IcyIcicle

Reputation: 765

The media_info package is in development and attempts to solve this problem.

https://pub.dev/packages/media_info

The documentation is found in the code at the moment. In the MediaInfo() class you can get the following information

Example

final MediaInfo _mediaInfo = MediaInfo();
...
   final Map<String, dynamic> info = await _mediaInfo.getMediaInfo("your/media/file");
   final yourPropertyValue = info["yourPropertyKey"];
...

Replace yourPropertyKey with one of the keys that are found in the source code here and I listed them below for each file type.

Images Videos Audio
mimeType mimeType mimeType
width width
height height
frameRate
durationMs durationMs
numTracks
bitrate

Upvotes: 3

aedolfi
aedolfi

Reputation: 101

Late answer but maybe it still helps someone.

You can try ffmpeg_kit_flutter like so:

import 'package:ffmpeg_kit_flutter_full_gpl/ffprobe_kit.dart';

Future<double> getFileDuration(String mediaPath) async {
  final mediaInfoSession = await FFprobeKit.getMediaInformation(mediaPath);
  final mediaInfo = mediaInfoSession.getMediaInformation()!;

  // the given duration is in fractional seconds
  final duration = double.parse(mediaInfo.getDuration()!);
  print('Duration: $duration');
  return duration;
}

Of course ffmpeg is a very large libary for such a small task but it advoids playing the audio file which I did not like either.

Upvotes: 6

Ashu Pathak
Ashu Pathak

Reputation: 39

First add "just_audio:" in pubspec.yaml and import it in the required screen file. Now you can adjust the code according to your need:

final player = AudioPlayer();

void getDuration(String path) async {
    var duration = await player.setFilePath(path);
    return duration;
}

Upvotes: 0

Mark Volkmann
Mark Volkmann

Reputation: 979

This works for me:

    // 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;
    });

Upvotes: 0

Kashish Khullar
Kashish Khullar

Reputation: 424

If you still want to use AudioPlayers and AudioCache then load the file before actually playing it. Otherwise you will get an error when implementing the division of your Slider.

Use AudioCache to pre-load the file, this would return a future of the file. Chain it with then block and use the passed file which would have path in it. Set the url on the audio player and return it. Chain this another then block and in that return the future from getDuration call. Now use this in your future builder with a spinning loader when the snapshot is null and your music player when snapshot has a value.

Consider this example:

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());
}

I called this function in the initState to avoid multiple calls to the future and stored the future in a Future variable.

  @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();
  }

Next I used the _loadFile variable in my future builder. And in the future builder I also added a loader.

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

Upvotes: 4

Teja
Teja

Reputation: 807

I am using the below code to get an audio file duration. audioplayers

First call

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

it will trigger the audio player onDurationChanged listener function from there we will get the max duration of and audio file without playing.

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

});

Upvotes: -1

Milan R Dhameliya
Milan R Dhameliya

Reputation: 89

By This Method you will get Duration in this formate Max duration: 0:06:12.715000

  AudioPlayer audioPlayer = AudioPlayer();

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

Upvotes: -1

Henok
Henok

Reputation: 3383

This is a late answer but incase if you are still wondering how to do that, There is a audio library just_audio

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

Works on both android and IOS, supports both local files and download urls.

Upvotes: 10

Ravinder Kumar
Ravinder Kumar

Reputation: 7990

Use this library audioplayers,

Fetch duration event like this

This event returns the duration of the file when it's available (it might take a while because it's being downloaded or buffered).

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

enter image description here

Upvotes: -2

Related Questions