2020-07-23

2020-07-23  本文已影响0人  声声乌龙_yq

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

当音频可倍速播放之后,可以音频的时间为轴来控制视频帧的渲染速度,进而达到音视频同播播放的效果。

上一篇 下一篇

猜你喜欢

热点阅读