.We have an AS3 player that requires Flash 10 (to overcome old issues with 9 and playback offsets) to handle clipping of audio. However when I select start and end points to playback from, many times what is played back doesn't match the same clip as what is played in Audacity. Here are some details on my test mp3 (results from ffmpeg)
libavutil 49.10. 0 / 49.10. 0
libavcodec 52. 0. 0 / 52. 0. 0
libavformat 52.22. 1 / 52.22. 1
libavdevice 52. 1. 0 / 52. 1. 0
libswscale 0. 6. 1 / 0. 6. 1
libpostproc 51. 2. 0 / 51. 2. 0
built on Sep 24 2008 15:49:57, gcc: 4.2.4 (TDM-1 for MinGW)
Input #0, mp3, from 'reagan_challenger.mp3':
Duration: 00:00:14.62, start: 0.000000, bitrate: 127 kb/s
Stream #0.0: Audio: mp3, 44100 Hz, stereo, s16, 128 kb/s
Original url: http://ericmalone.net/test_media/reagan_challenger.mp3
Clipped url: http://ericmalone.net/test_media/reagan_clipped.wav
Clip was created on the backend using ffmpeg to get the clip from 4017ms - 7400ms:
ffmpeg -i reagan_challenger.mp3 -ss 4.017 -t 3.383 reagan_clipped.wav
I've also clipped the file using Audacity to the slightly less accurate positions 4.017676 seconds - 7.401333 seconds at http://ericmalone.net/test_media/reagan_challenger_from_audacity.wav
Here's the clipped portion playing back via the code below http://ericmalone.net/test_media/SoundExample.swf
Notice that the word challenger completes in the flash playback, but is truncated in both the Audacity and ffmpeg based clippings.
The method by which we stop audio playback in flash is fairly standard. I've extracted the sound bits to a test class. Here's the relevant code
package {
import flash.display.Sprite;
import flash.events.*;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.net.URLRequest;
import flash.text.TextField;
import flash.utils.Timer;
public class SoundExample extends Sprite {
private var url:String = "http://www.ericmalone.net/test_media/reagan_challenger.mp3";
private var soundFactory:Sound;
private var song:SoundChannel;
private var clipStart:int = 4017;
private var clipEnd:int = 7400;
private var timer:Timer;
private var timerInterval:uint = 20;
private var textField:TextField;
public function SoundExample() {
var request:URLRequest = new URLRequest(url);
soundFactory = new Sound();
soundFactory.addEventListener(Event.COMPLETE, completeHandler);
soundFactory.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
soundFactory.load(request);
textField = new TextField();
textField.wordWrap = true;
textField.width = 500;
addChild(textField);
}
private function completeHandler(event:Event):void {
output("file completely loaded and playing");
timer = new Timer(timerInterval);
timer.addEventListener(TimerEvent.TIMER, onTimer);
song = soundFactory.play(clipStart);
timer.start();
}
private function ioErrorHandler(event:Event):void {
output("ioErrorHandler: " + event);
}
private function onTimer(event:TimerEvent):void
{
// stop playback if position is greater than clip end
// or if there's less duration left than difference of the timer and current position
if((song.position >= clipEnd || clipEnd - song.position < timerInterval))
{
timer.stop();
song.stop();
output("Ending playback at " + song.position + " to be as close to " + clipEnd + " as possible");
}
}
private function output(str):void
{
textField.text = str;
trace(str);
}
}
}
So the question is, is there a better way to get more accurate playback from within flash? Does it depend on codec/sampling rate/etc?