我们有一台需要Flash 10的AS3播放器(克服9和播放偏移的旧问题)来处理音频剪辑。但是,当我选择开始和结束点进行播放时,很多时候播放的内容与Audacity中播放的内容不匹配。以下是我的测试mp3的一些细节(来自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
原始网址:http://ericmalone.net/test_media/reagan_challenger.mp3
剪切网址:http://ericmalone.net/test_media/reagan_clipped.wav
使用ffmpeg在后端创建剪辑以从4017ms - 7400ms获取剪辑:
ffmpeg -i reagan_challenger.mp3 -ss 4.017 -t 3.383 reagan_clipped.wav
我还使用Audacity将文件剪切到略微不准确的位置4.017676秒 - http://ericmalone.net/test_media/reagan_challenger_from_audacity.wav时的7.401333秒
这是通过http://ericmalone.net/test_media/SoundExample.swf
下面显示的代码播放的剪辑部分请注意, challenger 一词在Flash播放中完成,但在Audacity和基于ffmpeg的剪辑中都被截断。
我们在闪存中停止音频播放的方法是相当标准的。我已将声音位提取到测试类。这是相关代码
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);
}
}
}
所以问题是,是否有更好的方法可以在闪存中获得更准确的播放效果?它取决于编解码器/采样率/等吗?
答案 0 :(得分:2)
不直接关于正确的mp3编码,但可以帮助......
您必须知道Timer类具有一定的精度余量。
你的例子中的测试对我来说听起来不错(中间没有点击)我接近0.2%接近期望的结果,这是完全可以接受的IMO。
关于代码,我想提供一个细节,给出你的例子中的以下条件:
clipEnd - song.position < timerInterval
想象一下以下场景:
如果条件没有取消,我猜它会停在7401(100.01%)
也许你应该尝试类似的东西(小心,盲目编码):
if(song.position >= clipEnd || (clipEnd - song.position < (song.position + timerInterval) - clipEnd))
{
// Stop Timer
}
延迟将取决于您执行的代码,计算机等。但我建议使用不同的间隔值来保持接近最佳“均匀度”。
另外,请确保您没有其他方法来延迟执行计时器事件。 为此,您应该将此Timer部分隔离开以对其进行基准测试(同时删除声音)。