[FFmpeg + OpenGL + OpenSL ES]音視訊同步- 8
音視訊同步實現理論
PTS和time_base
PTS即顯示時間戳,這個時間戳用來告訴播放器該在什麼時候顯示這一幀的資料。time_base即時間度量單位(時間基),可以類比:米、千克這種單位。
分別獲取音訊和視訊的PTS(播放時間戳):
PTS = avFrame->pts * av_q2d(avStream->time_base);
獲取音視訊PTS差值,根據差值來設定視訊的睡眠時間達到和音訊的相對同步。視訊快了就休眠久點,視訊慢了就休眠少點,來達到同步。
在 Video.h 中宣告一個 audio 成員變數和 clock 成員屬性用來儲存當前視訊的時間戳 並且宣告一個函式用來計算音訊視訊的差值
//音訊物件
WlAudio *audio = NULL;
//時鐘
double clock = 0;
double getFrameDiffTime(AVFrame *avFrame);
在 Video.cpp 中寫方法宣告
double WlVideo::getFrameDiffTime(AVFrame *avFrame) {
//返回當前avFrame的顯示時間戳
double pts = av_frame_get_best_effort_timestamp(avFrame);
if (pts == AV_NOPTS_VALUE) {
pts = 0;
}
pts *= av_q2d(time_base);
if (pts > 0) {
clock = pts;
}
double diff = audio->clock - clock;
return diff;
}
在 FFmpeg.cpp 中的 start 函式中將 audio 賦值給 video
//把video設定到視訊當中
video->audio = audio;
在 video.cpp 渲染之前呼叫函式計算diff
double diff = video->getFrameDiffTime(avFrame);
根據音訊和視訊時間戳的差值增大或減小視訊渲染的睡眠時長
在 video.h 中新建三個成員變數用來計算
//時鐘
double clock = 0;
double delayTime = 0;
double defaultDelayTime = 0.004;
宣告一個根據音視訊時間戳差值 增大或減小視訊渲染的睡眠時長的函式
double getDelayTime(double diff);
在 video.cpp 寫這個函式的實現
double WlVideo::getDelayTime(double diff) {
if (diff > 0.003) {
delayTime = delayTime * 2 / 3;
if (delayTime < defaultDelayTime / 2) {
delayTime = defaultDelayTime * 2 / 3;
} else if (delayTime > defaultDelayTime * 2) {
delayTime = defaultDelayTime * 2;
}
} else if (diff < -0.003) {
delayTime = delayTime * 3 / 2;
if (delayTime < defaultDelayTime / 2) {
delayTime = defaultDelayTime * 2 / 3;
} else if (delayTime > defaultDelayTime * 2) {
delayTime = defaultDelayTime * 2;
}
} else if (diff == 0.003) {
}
if (diff >= 0.5) {
delayTime = 0;
} else if (diff <= 0.5) {
delayTime = defaultDelayTime * 2;
}
if (fabs(diff) > 10) {
//音訊不存在
delayTime = defaultDelayTime;
}
return delayTime;
}
在渲染下面呼叫
av_usleep(video->getDelayTime(diff) * 1000 * 1000);
相關文章
- FFmpeg+OpenGL ES+OpenSL ES打造Android視訊播放器課程總結Android播放器
- FFmpeg音視訊同步
- HarmonyOS音訊開發指導:使用OpenSL ES開發音訊播放功能音訊
- Android音視訊(六) 使用OpenGL ES 3.0預覽CameraAndroid
- 使用FFmpeg處理音視訊
- FFmpeg開發筆記(八):ffmpeg解碼音訊並使用SDL同步音訊播放筆記音訊
- ffmpeg實戰-音視訊合成案例
- ffmpeg命令錄製windows音視訊Windows
- FFmpeg+SDL2實現簡易音視訊同步播放器播放器
- 短視訊影象處理 OpenGL ES 實踐
- C#程式呼叫FFmpeg操作音視訊C#
- ffmpeg實戰-音視訊基礎概念
- FFmpeg音視訊編譯配置選項編譯
- MediaCodec、OpenGL、OpenSL/AudioTrack 實現一款簡單的視訊播放器播放器
- FFMPEG視音訊編解碼學習(1)音訊
- FFmpeg音訊解碼音訊
- 適用於Android的OpenSL ES指南-OpenSL ES的Android擴充套件Android套件
- OpenGL/OpenGL ES 初探
- 十、詳解FFplay音視訊同步
- ijkplayer 音視訊同步流程分析
- 如何在PR中同步音訊和視訊音訊
- ffmpeg解碼音訊流音訊
- 微信下載錄音檔案(音軌分離 ffmpeg視訊合成)
- WebRTC 音視訊同步原理與實現Web
- 音視訊基本概念和FFmpeg的簡單入門
- wavesurfer fluent-ffmpeg提取音訊音訊
- ffmpeg 去除音訊中的靜音音訊
- Mac音訊和視訊同步工具:Red Giant PluralEyesMac音訊
- 實戰解析 | 同步音視訊解決方案
- 短視訊原始碼,在Android 中opengl es實現燈光效果原始碼Android
- php ffmpeg 視訊擷取PHP
- 短視訊“音訊化”,音樂“視訊化”音訊
- Android OpenGL ES 開發(二): OpenGL ES 環境搭建Android
- ijkplayer 音視訊同步時間的計算
- OpenGL ES on iOS — AssimpiOS
- OpenGL ES 入門
- OpenGL ES on iOS --- AssimpiOS
- 音視訊--音訊入門音訊