我正在尝试使用ffmpeg-sdl2和emscripten编写sdl2视频播放器。
我有一个解码数据包并将缓冲区添加到SDL_QueuAudio的函数。我在js中这样称呼queueAudioFrame()
:
setInterval(function () {
this._queueAudioFrame();
}, 1);
这是实现的C端:
int DecodeAudioPacket(AVPacket packet, AVCodecContext* ctx, uint8_t* audioBuf, int bufSize)
{
AVFrame* frame = NULL;
uint8_t converted_data[(192000 * 3) / 2];
uint8_t* converted;
int len1, len2, dataSize = 0;
if (!frame)
{
frame = av_frame_alloc();
converted = &converted_data[0];
}
int gotFrame = 0;
len1 = avcodec_decode_audio4(ctx, frame, &gotFrame, &packet);
if (len1 < 0)
{
return 0;
}
if (gotFrame)
{
dataSize = av_samples_get_buffer_size(NULL, ctx->channels, frame->nb_samples, ctx->sample_fmt, 1);
int outSize = av_samples_get_buffer_size(NULL, ctx->channels, frame->nb_samples, AV_SAMPLE_FMT_FLT, 1);
len2 = swr_convert(swrCtx, &converted, frame->nb_samples, (const uint8_t**)&frame->data[0], frame->nb_samples);
memcpy(audioBuf, converted_data, outSize);
dataSize = outSize;
}
if (packet.data)
{
av_free_packet(&packet);
}
if (dataSize <= 0) {
/* No data yet, get more frames */
return 0;
}
/* We have data, return it and come back for more later */
return dataSize;
}
void EMSCRIPTEN_KEEPALIVE queueAudioFrame()
{
if (av_read_frame(audiopFormatCtx, &audiopacket) >= 0)
{
if (audiopacket.stream_index != videoStream)
{
uint8_t audioBuf[(192000 * 3) / 2];
int decodeSize = DecodeAudioPacket(audiopacket, audioCtx, audioBuf, sizeof(audioBuf));
queued = SDL_GetQueuedAudioSize(1);
printf("Decoded bytes from frame: %d & Device has %u bytes queued. \n", decodeSize, queued);
SDL_QueueAudio(1, audioBuf, decodeSize);
}
}
}
我从法典和wantedSpec.freq = audioCtx->sample_rate;
获得了采样率。问题是音频播放速度太快,无论我设置为wantSpec.freq还是wantSpec.samples速度的值不变。是什么原因造成的?