游戏开发需要具备哪些技术_短视频 SDK 开发 (一) 开发一款短视频 SDK 需要具备哪些知识?...
2020 年要屬什么最火,肯定是短視頻和直播帶貨了。我自己基本上每天晚上睡覺之前都會(huì)刷一會(huì)兒 douyin 短視頻,不得不承認(rèn) douyin 的推薦算法是真 nb ,推薦的都是我的最愛 ??。那么 douyin 短視頻這么 nb 我們可不可以自己模仿著也做一個(gè)? 想想都覺得難啊,但是還是可以模仿著做一個(gè)的。我們先來看一下效果,這只是第一個(gè)版本,具備的功能有限。后面會(huì)一直持續(xù)迭代下去!
那么,作為一個(gè)音視頻零基礎(chǔ)的人來說, 開發(fā)一款短視頻 SDK 到底需要具備哪些知識(shí)呢? 下面就由我為大家介紹一翻(ps:以下學(xué)習(xí)路徑僅代表個(gè)人觀點(diǎn))。
?接下來的日子我準(zhǔn)備從 0-1 寫一個(gè)如何開發(fā)一款音視頻編輯的 SDK 系列文章,下面是我的計(jì)劃。
短視頻 SDK 開發(fā) (一) 開發(fā)一款短視頻 SDK 需要具備哪些知識(shí)?
短視頻 SDK 開發(fā) (二) 短視頻 SDK 架構(gòu)設(shè)計(jì)
短視頻 SDK 開發(fā) (三) FFmpeg + OpenGL ES + OpenSL ES + soundtouch 實(shí)現(xiàn)音視頻播放器
短視頻 SDK 開發(fā) (四) Camera + MediaCodec + OpenGL ES + OpenSL ES + FFmpeg MP4Muxer 實(shí)現(xiàn)音視頻實(shí)時(shí)錄制封裝為 MP4
短視頻 SDK 開發(fā) (五) 濾鏡、貼紙、水印實(shí)現(xiàn)
短視頻 SDK 開發(fā) (六) 美顏特效實(shí)現(xiàn)
短視頻 SDK 開發(fā) (七) 音視頻剪輯實(shí)現(xiàn)
?基礎(chǔ)知識(shí)
1、你必須要有?「C/C++」?開發(fā)語言基礎(chǔ),可以看我之前寫的文章
- 音視頻學(xué)習(xí) (一) C 語言入門
- 音視頻學(xué)習(xí) (二) C++ 語言入門
2、接下來就需要掌握?「JNI」?基礎(chǔ)了
- 音視頻學(xué)習(xí) (三) JNI 從入門到掌握
3、有了?「C/C++/JNI」?基礎(chǔ),你還要學(xué)會(huì)如何交叉編譯?「FFmpeg」?等 C/C++ 庫
- 音視頻學(xué)習(xí) (四) 交叉編譯動(dòng)態(tài)庫、靜態(tài)庫的入門學(xué)習(xí)
- 音視頻學(xué)習(xí) (五) Shell 腳本入門
- 音視頻學(xué)習(xí) (六) FFmpeg 4.2.2 交叉編譯
4、有了以上的基礎(chǔ),那么就可以開始了解 音視頻 的基礎(chǔ)知識(shí)了
雷神-視音頻編解碼技術(shù)零基礎(chǔ)學(xué)習(xí)方法
雷神-視音頻數(shù)據(jù)處理入門:RGB、YUV像素?cái)?shù)據(jù)處理
雷神-視音頻數(shù)據(jù)處理入門:PCM音頻采樣數(shù)據(jù)處理
雷神-視音頻數(shù)據(jù)處理入門:H.264視頻碼流解析
雷神-視音頻數(shù)據(jù)處理入門:AAC音頻碼流解析
音視頻學(xué)習(xí) (七) 掌握音頻基礎(chǔ)知識(shí)并使用 AudioTrack、OpenSL ES 渲染 PCM 數(shù)據(jù)
音視頻學(xué)習(xí) (八) 掌握視頻基礎(chǔ)知識(shí)并使用 OpenGL ES 2.0 渲染 YUV 數(shù)據(jù)
5、現(xiàn)在可以入手音視頻 AAC 、H264 軟硬編解碼了
| fdkaac_audio_encode_decode | Libfdk-aac 音頻編解碼 |
| x264_video_encode | Libx264 視頻編碼 |
| mediacodec_audio_encode_decode | Android MediaCodec AAC 硬編解碼 |
| mediacodec_video_encode_decode | Android MediaCodec H264 硬編解碼 |
| ffmpeg_audio_encode_decode | FFmpeg API 實(shí)現(xiàn)音頻 AAC 軟編解碼 |
| ffmpeg_video_encode_decode | FFmpeg API 實(shí)現(xiàn)視頻 H264 軟編解碼 |
| lame_ffmpeg_mp3_encode_decode | MP3 編解碼 |
| JavaAVPlayer | Java API 實(shí)現(xiàn)音視頻播放(mp3/mp4/pcm/yuv) |
| NativeAVPlayer | Native 端實(shí)現(xiàn)音視頻播放(PCM/YUV) |
| ffmpeg_muxer | 基于 h264,AAC 文件打包為 MP4 |
基礎(chǔ)知識(shí)差不多就這些了,如果有落下的后面再補(bǔ)上
中級(jí)知識(shí)
1、FFmpeg + OpenGL ES + OpenSL ES + soundtouch 完成音視頻播放
- Google 官方的音視頻播放庫 -grafika
- bilibili 官方開源的音視頻播放庫- ijkplayer
- 當(dāng)然也可以參考我自己的 AVEditor 音視頻播放模塊
2、OpenGL ES 渲染視頻是必須要會(huì)的
- NDK_OpenGLES_3_0
3、Camera + MediaCodec + OpenGL ES + OpenSL ES + FFmpeg MP4Muxer 實(shí)現(xiàn)音視頻錄制為 MP4 格式
- camera_recorder
4、RTMP 推流實(shí)現(xiàn)
- AVRtmpPushSDK
高級(jí)知識(shí)
1、音視頻變速、變調(diào)錄制
- 音頻-soundtouch
- 視頻修改時(shí)間戳即可達(dá)到變速錄制
2、音視頻錄制實(shí)時(shí)濾鏡實(shí)現(xiàn)
- android-gpuimage
3、分段錄制、水印、背景音
「分段錄制:」?每次錄制完成將錄制的路徑保存下來,最后將這些 MP4 的文件合并為一個(gè) MP4 文件
「水印:」??拿著上一個(gè)視頻處理的 紋理 ID ,在這基礎(chǔ)上渲染一個(gè) BItmap 即可
「背景音混音:」?可以參考如下實(shí)現(xiàn)代碼
/**?*?參考地址:https://www.shangmayuan.com/a/6daeefedbecb463f9dfce318.html
?*?歸一算法:http://www.cppblog.com/jinq0123/archive/2007/10/31/35615.aspx
?*?能量值實(shí)現(xiàn):https://www.jianshu.com/p/d3745dd23056
?*?實(shí)現(xiàn)原理:
?*?其實(shí)音頻混音的核心原理就是將兩個(gè)音頻的原始byte數(shù)據(jù)進(jìn)行疊加,
?*?很是簡(jiǎn)單的?+?起來,好比某個(gè)位置的數(shù)據(jù)是?1?而另外一個(gè)音頻一樣位置是?2?加起來就是3,
?*?這樣就完成了音頻的混音,固然這是最基礎(chǔ)也是最垃圾的混音算法,咱們這里會(huì)介紹其中的一種混音算法,
?*?基本上能夠達(dá)到商業(yè)使用的。那就是歸一化混音算法。
?*
?*????C?=?A?+?B?-?A?*?B?/?(數(shù)據(jù)類型的最大值);
?*????byte數(shù)據(jù)就是
?*?????C?=?A?+?B?-?A?*?B?/?127;
?*?????short數(shù)據(jù)就是
?*?????C?=?A?+?B?-?A?*?B?/?32767;
?*?????//vol的取值范圍?一般是小于10,大于0的,若是是0的話,就沒有聲音了,若是太大了就會(huì)出現(xiàn)雜音
?*?????C?=?A?*?vol;
?*
?*
?*?????混音算法總結(jié):
?*?????總結(jié)一下我對(duì)混音算法的學(xué)習(xí),大概有以下幾種方式:
?*??????1.?直接加和
?*??????2.?加和后再除以混音通道數(shù),防止溢出
?*????? 3. 加和并箝位,如有溢出就設(shè)最大值
?*??????4.?飽和處理,接近最大值時(shí)進(jìn)行扭曲(“軟件混音的實(shí)現(xiàn)”一文算法就是這類)
?*????? 5. 歸一化處理,全部乘個(gè)系數(shù),使幅值歸一化。(只適用于文件)
?*????? 6. 衰減因子法,用衰減因子限制幅值[1]。
?*/
extern?"C"
JNIEXPORT?jbyteArray?JNICALLJava_org_doubango_ngn_media_mixer_MultiAudioMixer_audioMix2(JNIEnv?*env,?jobject?instance,
????????????????????????????????????????????????????????????jbyteArray?sourceA_,
????????????????????????????????????????????????????????????jbyteArray?sourceB_,
????????????????????????????????????????????????????????????jbyteArray?dst_,?jfloat?firstVol,
????????????????????????????????????????????????????????????jfloat?secondVol)?{
????jbyte?*sourceA?=?env->GetByteArrayElements(sourceA_,?NULL);
????jbyte?*sourceB?=?env->GetByteArrayElements(sourceB_,?NULL);
????jbyte?*dst?=?env->GetByteArrayElements(dst_,?NULL);
????//歸一化混音
????int?aL?=?env->GetArrayLength(sourceA_);
????int?bL?=?env->GetArrayLength(sourceB_);
????//除以通道數(shù)量
????int?row?=?aL?/?2;
????short?sA[row];
????for?(int?i?=?0;?i?????????sA[i]?=?(short)?((sourceA[i?*?2]?&?0xff)?|?(sourceA[i?*?2?+?1]?&?0xff)?<8);
????}
????short?sB[row];
????for?(int?i?=?0;?i?????????sB[i]?=?(short)?((sourceB[i?*?2]?&?0xff)?|?(sourceB[i?*?2?+?1]?&?0xff)?<8);
????}
????short?result[row];
????for?(int?i?=?0;?i?????????int?a?=?(int)?(sA[i]?*?firstVol);
????????int?b?=?(int)?(sB[i]?*?secondVol);
????????if?(a?0?&&?b?0)?{
????????????int?i1?=?a?+?b?-?a?*?b?/?(-32768);
????????????if?(i1?>?32768)?{
????????????????result[i]?=?32767;
????????????}?else?if?(i1?-32768)?{
????????????????result[i]?=?-32768;
????????????}?else?{
????????????????result[i]?=?(short)?i1;
????????????}
????????}?else?if?(a?>?0?&&?b?>?0)?{
????????????int?i1?=?a?+?b?-?a?*?b?/?32767;
????????????if?(i1?>?32767)?{
????????????????result[i]?=?32767;
????????????}?else?if?(i1?-32768)?{
????????????????result[i]?=?-32768;
????????????}?else?{
????????????????result[i]?=?(short)?i1;
????????????}
????????}?else?{
????????????int?i1?=?a?+?b;
????????????if?(i1?>?32767)?{
????????????????result[i]?=?32767;
????????????}?else?if?(i1?-32768)?{
????????????????result[i]?=?-32768;
????????????}?else?{
????????????????result[i]?=?(short)?i1;
????????????}
????????}
????}
????for?(int?i?=?0;?i?????????dst[i?*?2?+?1]?=?(jbyte)?((result[i]?&?0xFF00)?>>?8);
????????dst[i?*?2]?=?(jbyte)?(result[i]?&?0x00FF);
????}
????jbyteArray?result1?=?env->NewByteArray(aL);
????env->SetByteArrayRegion(result1,?0,?aL,?dst);
????env->ReleaseByteArrayElements(sourceA_,?sourceA,?0);
????env->ReleaseByteArrayElements(sourceB_,?sourceB,?0);
????env->ReleaseByteArrayElements(dst_,?dst,?0);
????return?result1;
}
5、人臉識(shí)別-特效
- 可以使用 OpenCV 來做人臉識(shí)別,拿到人臉特征點(diǎn)位,最后利用這些點(diǎn)位用 OpenGL 繪制繪制出來就行了。
6、音視頻剪輯技術(shù)
書籍推薦
- <>
- <>
- <>
總結(jié)
目前能想到的從 0-1 開發(fā)一款短視頻 SDK 需要具備的知識(shí)大概就是這些。其實(shí)學(xué)習(xí)這些知識(shí)相對(duì)而言時(shí)間成本都比較高,因?yàn)槊恳粋€(gè)知識(shí)點(diǎn)基本上都是一個(gè)獨(dú)立的,就拿 OpenGL 來說, 要學(xué)這門知識(shí)基本上肯定是要按 月 為單位來計(jì)算。當(dāng)然不要看著學(xué)習(xí)成本高,就直接放棄了,一般來說高投入肯定會(huì)有高回報(bào)的。好了,短視頻入門開發(fā)就介紹到這里了。下面推薦一個(gè)目前我自己開源的零基礎(chǔ)音視頻進(jìn)階路線項(xiàng)目, 有需要的可以關(guān)注 star 一波 AVSample
貼一張進(jìn)階路線圖
短視頻 SDK 項(xiàng)目有更新都會(huì)提交到此處 AVEditor (ps:目前只是一個(gè)半成品,功能尚未開發(fā)完成)
總結(jié)
以上是生活随笔為你收集整理的游戏开发需要具备哪些技术_短视频 SDK 开发 (一) 开发一款短视频 SDK 需要具备哪些知识?...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 京东金条怎么协商还款,有以下两步
- 下一篇: winform响应时间最长是多少分钟_史