簡體   English   中英

libwebm(VP8 / Opus)的非音頻視頻—同步音頻-

[英]Non-audible videos with libwebm (VP8/Opus) — Syncing audio --

我正在嘗試創建一個非常簡單的webm(vp8 / opus)編碼器,但是我無法使音頻正常工作。

ffprobe會檢測文件格式和持續時間

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

VLC媒體信息對話框

視頻可以在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();

更新#1:似乎問題在於WebM要求對音頻和視頻軌道進行隔行掃描。 但是我不知道如何同步音頻。 我應該計算幀持續時間,然后對等效音頻樣本進行編碼嗎?

問題是我丟失了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;
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM