【发布时间】:2019-03-31 07:19:59
【问题描述】:
我正在尝试使用 SDL2 和 FFmpeg 播放 mp4 文件中的音频,而使用 SDL_QueueAudio 似乎比设置回调要容易得多。
我发现的所有解决方案,无论是在此处还是在 dranger tutorials 中,都已弃用或使用回调。我尝试使用 ffmpeg 和 sdl 标签(没有很多)浏览所有问题,但无济于事。我尝试将 dranger 教程转换为使用未弃用的调用,但遇到了同样的问题。我正在使用 C、FFmpeg 4.1 和 SDL 2.0.9。
这是 AVCodecContext 和 AVCodec 的设置:
int audioStream = -1;
for (i = 0; i < formatContext->nb_streams; i++) {
if (audioStream < 0 && formatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
audioStream = i;
}
}
AVCodecParameters *audioParams = formatContext->streams[audioStream]->codecpar;
AVCodec *audioCodec = avcodec_find_decoder(audioParams->codec_id);
AVCodecContext *audioCodecCtx = avcodec_alloc_context3(NULL);
avcodec_open2(audioCodecCtx, audioCodec, NULL);
SDL_Init(SDL_INIT_AUDIO)
SDL_AudioSpec desired, obtained;
SDL_zero(desired);
SDL_zero(obtained);
desired.freq = audioCodecCtx->sample_rate;
desired.format = AUDIO_F32SYS;
desired.channels = audioCodecCtx->channels;
desired.silence = 0;
desired.samples = AUDIO_BUFFER_SIZE;
SDL_AudioDeviceID audioDevice = SDL_OpenAudioDevice(NULL, 0, &desired, &obtained, SDL_AUDIO_ALLOW_ANY_CHANGE);
这是主要的数据包解码循环:
while (av_read_frame(formatContext, &packet) >= 0) {
if (packet.stream_index == audioStream) {
if (!avcodec_send_packet(audioCodecCtx, &packet)) {
avcodec_receive_frame(audioCodecCtx, audioFrame);
SDL_QueueAudio(audioDevice, audioFrame->data[0], audioFrame->linesize[0]);
}
}
}
音频以正确的速度播放,但音调比实际高得多。我希望它听起来与任何媒体播放器中的声音相同。
编辑:我刚刚意识到测试视频有立体声音频,但我只是在排队audioFrame.data[0],我认为这意味着我只播放一个频道。我尝试排队 audioFrame.data[1] 也有数据,但它没有解决问题。我是否正确,如果正确,我该如何播放两个频道?
【问题讨论】:
-
您检查过
obtained结构中的值(主要是频率)吗? -
对于我的测试视频,
obtained.freq是 44100,与 VLC 报告的相同。