I have recently had the same requirement, and although I know of a way to do this on android and ios/mac I wanted a way that would work whereever e.g. cocos2d-html5 so I did a little bit of googling and found out that you can get the length of the sound file by using this command (on stackoverflow… cannot find the original )
#!/bin/bash
# call me with audiolength.sh directory
# e.g. ./audiolength.sh .
# or ./audiolength.sh my-mp3-collection
echo "{"
for file in $1/*.caf
do
echo "\""$file"\":"
ffmpeg -i "$file" 2>&1 | egrep "Duration"| cut -d ' ' -f 4 | sed s/,//
echo ","
done
echo "}"
The shell script prints out the file names and the durations of all my files - I then tidy the output up into a json file and use it for looking up audio file durations at runtime…
I know this probably sounds cluncky, but it works really well and removes the need for relying on the api.
I just tried AudioEngine with cocos2d 3.6, but it does not work at all for iOS. All I get from play2d() is -1. Is that broken? Sound formats tested are m4a and wav. These work fine using SimpleAudioEngine. AudioEngine API is funny because you have to play a sound in order to get the duration of it? Well my attempt in implementing a duration method on top of that was to play the sound at 0 volume, retrieve the duration, then immediately stop it, and return the duration. Well it never worked because AudioEngine just could never play my audio files. Shucks.
Hey, checking in after a few months since the last post. Any chance we could get this working in Cocos Creator? This seems like a pretty basic, necessary feature.
Hey, it’s been over a month since my last post, and I haven’t heard anything from you guys yet. Were you able to take a look?
We’re dealing with arbitrarily length audio files now, and so we really need this feature. It shouldn’t be too hard to calculate on your end by dividing the number of samples by the sample rate and returning that value.
If there is anything I can do to help you prioritize this, please just let me know. Thanks!
the new audioEngine doesn’t use the AVAudioPlayer for streaming mp3 through hardware on IOS, it streams them from pcm data, which needs to first be decoded by soft, which takes time and CPU cycles.
I have created A SimpleAudioPlayer that inherits AudioPlayer, and that just overrides the play/pause/resume/setVolume/setTime/getDuration methods from the AudioPlayer to use the SimpleAudioEngine API instead, which use the NSSound class internally( which uses CoreAudio classes for mp3 reading)
I can see a 10% CPU gain and roughly a 2 to 3 times less latency using this method.
It would be nice to have a getDuration method, even in the SimpleAudioEngine, or to provide a way to use the hardware mp3 streamer in the AudioPlayer…
After poking around a bit, the NSSound class that is used by the SimpleAudioEngine has a duration property which is quite accurate.
adding a getDuration method to the SimpleAudioEngine is really just a matter of adding the right getters (for ios and mac), which I have done in my cocos fork. It took me around 15 mn.
instead of the preload method, and pausing it immediately. And then when its actually time to play the audio, I can do seek to 0, reset the volume to 1, and resume the audio. At this point, calling getDuration will work.