2016-02-09 2 views
0

Я пытаюсь создать очень простой веб-редактор (vp8/opus), однако я не могу заставить аудио работать.Неслучайные видео с libwebm (VP8/Opus) - Синхронизация звука -

ffprobe делает детектировать формат и продолжительность

Stream #1:0(eng): Audio: opus, 48000 Hz, mono, fltp (default)

VLC Media information dialog

видео можно воспроизводить только штрафом в VLC и Chrome, но без звука, по какой-то причине звук input bitrate является всегда 0

Большая часть кода кодирования аудио была скопирована с https://github.com/fnordware/AdobeWebM/blob/master/src/premiere/WebM_Premiere_Export.cpp

Вот соответствующий код:

static const long long kTimeScale = 1000000000LL; 

MkvWriter writer; 
writer.Open("video.webm"); 

Segment mux_seg; 
mux_seg.Init(&writer); 

// VPX encoding... 

int16_t pcm[SAMPLES]; 
uint64_t audio_track_id = mux_seg.AddAudioTrack(SAMPLE_RATE, 1, 0); 
mkvmuxer::AudioTrack *audioTrack = (mkvmuxer::AudioTrack*)mux_seg.GetTrackByNumber(audio_track_id); 
audioTrack->set_codec_id(mkvmuxer::Tracks::kOpusCodecId); 
audioTrack->set_seek_pre_roll(80000000); 
OpusEncoder *encoder = opus_encoder_create(SAMPLE_RATE, 1, OPUS_APPLICATION_AUDIO, NULL); 
opus_encoder_ctl(encoder, OPUS_SET_BITRATE(64000)); 
opus_int32 skip = 0; 
opus_encoder_ctl(encoder, OPUS_GET_LOOKAHEAD(&skip)); 
audioTrack->set_codec_delay(skip * kTimeScale/SAMPLE_RATE); 
mux_seg.CuesTrack(audio_track_id); 
uint64_t currentAudioSample = 0; 
uint64_t opus_ts = 0; 
while(has_frame) { 
    int bytes = opus_encode(encoder, pcm, SAMPLES, out, SAMPLES * 8); 
    opus_ts = currentAudioSample * kTimeScale/SAMPLE_RATE; 
    mux_seg.AddFrame(out, bytes, audio_track_id, opus_ts, true); 
    currentAudioSample += SAMPLES; 
} 

opus_encoder_destroy(encoder); 
mux_seg.Finalize(); 
writer.Close(); 

Update # 1: кажется, что проблема заключается в том, что WebM требует аудио и видео треков чередоваться. Однако я не могу понять, как синхронизировать звук. Должен ли я рассчитать продолжительность кадра, а затем закодировать эквивалентные образцы звука?

ответ

1

Проблема заключалась в том, что мне не хватало данных заголовка OGG, а временные метки звуковых кадров не были точными.

для заполнения ответа здесь - псевдокод для кодировщика.

const int kTicksPerSecond = 1000000000; // webm timescale 
const int kTimeScale = kTicksPerSecond/FPS; 
const int kTwoNanoSeconds = 1000000000; 

init_opus_encoder(); 
audioTrack->set_seek_pre_roll(80000000); 
audioTrack->set_codec_delay(opus_preskip); 
audioTrack->SetCodecPrivate(ogg_header_data, ogg_header_size); 

while(has_video_frame) { 
    encode_vpx_frame(); 
    video_pts = frame_index * kTimeScale; 
    muxer_segment.addFrame(frame_packet_data, packet_length, video_track_id, video_pts, packet_flags); 
    // fill the video frames gap with OPUS audio samples 
    while(audio_pts < video_pts + kTimeScale) { 
    encode_opus_frame(); 
    muxer_segment.addFrame(opus_frame_data, opus_frame_data_length, audio_track_id, audio_pts, true /* keyframe */); 
    audio_pts = curr_audio_samples * kTwoNanoSeconds/48000; 
    curr_audio_samples += 960; 
    } 
}