iOS 支持音视频倍速播放
基于使用ffmpeg+AudioUnit+OpenGL的一个视频播放器实现倍速播放功能:
用ffmpeg解码出得到PCM格式的音频数据,由AudioUnit播放音频,在播放之前通过sonic库转化为所需倍速的PCM格式音频
sonic是一个C++库,用法简单无需添加依赖库, 直接传入的是PCM格式,输出的也是PCM格式,这样的用起来很方便,不需要格式转换
sonic的关键代码
1.创建一个stream流,并设置相关参数
stream=sonicCreateStream((int)(sampleRate), (int)(channels));
sonicSetSpeed(stream, 1.0);//通过设置speed来实现倍速播放(声音不会变调)
sonicSetPitch(stream, 1.0);
sonicSetVolume(stream, 1.0);
sonicSetRate(stream, 1.0);//通过设置rate来实现倍速(声音会变调)
2、相关的转换代码
- (NSData *)setFloatData:(NSData *)data{
NSMutableData *sonicdDatas = [[NSMutableData alloc] init];
int lenBytes = (int)data.length;
float * dataBytes = (float *)[data bytes];
float * outBytes = (float *)malloc(lenBytes);
int samples = lenBytes/(sizeof(float)* sonicGetNumChannels(stream));
//传入数据,注意数据类型如果是short类型用 sonicWriteShortToStream(stream, dataBytes, samples),否则转换后声音会出现呲呲的噪音
int ret = sonicWriteFloatToStream(stream, dataBytes, samples);
if (ret) {
int available = sonicSamplesAvailable(stream) * sizeof(float) * sonicGetNumChannels(stream);
if (lenBytes > available) {
lenBytes = available;
}
outBytes = (float *)realloc(outBytes, lenBytes);
int samplesRead;
do {
samplesRead = sonicReadFloatFromStream(stream, outBytes, lenBytes/(sizeof(float)*sonicGetNumChannels(stream)));
if (samplesRead > 0) {
int bytesRead = samplesRead * sizeof(float) * sonicGetNumChannels(stream);
[sonicdDatas appendBytes:outBytes length:bytesRead];
}
} while (samplesRead > 0);
}
free(outBytes);
return sonicdDatas; //返回转换后的数据
}
3.通过改变speed的值来实现倍速播放
-(void)setPlaySpeed:(double)playSpeed{
_playSpeed = playSpeed;
sonicSetSpeed(stream, playSpeed);
}
当音频可倍速播放之后,可以音频的时间为轴来控制视频帧的渲染速度,进而达到音视频同播播放的效果。
网友评论