開源短視頻方案Android


trinity 是一個開源的拍攝和短視頻處理工具,用 kotlin 和 c++編寫,實現了大部分短視頻編輯軟件熱門功能

https://github.com/wlanjie/trinity? ( 不支持美顏 )

開發環境? NDK R20 / Kotlin 1.3.41
開源庫使用??fdk-aac / ffmpeg 3.4 / libx264 / xlogger / mnnkit
特效調試
項目中使用XCODE調試特效效果,使用前需要安裝GLFW
brew install glfw
然后使用XCODE打開library/src/main/cpp/opengl.xcodeproj即可
切換效果調試代碼
image_process.OnAction("param/blurScreen", 0);
自動化測試
自動化測試使用 UIAUTOMATOR2具體使用請參考文檔
使用方式
cd trinity
python trinity.py
然后使用
adb devices
在終端輸入設備名即可

使用(注意 SDK中沒有權限判斷)
添加依賴
dependencies {?implementation 'com.github.wla0jie:trinity:0.2.8}
權限要求
<uses-permission android:name="android.permission.CAMERA" /><uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />


錄制
配置參數
val preview = findViewById<TrinityPreviewView>(R.id.preview)
創建錄制接口實例
mRecord = TrinityRecord(preview)
銷毀錄制接口實例
mRecord.release()

回調設置
設置視頻渲染回調
mRecord.setOnRenderListener(this)
設置錄制進度回調
mRecord.setOnRecordingListener(this)
設置相機回調
mRecord.setCameraCallback(this)

開啟預覽
開始預覽
mRecord.startPreview()
結束預覽
mRecord.stopPreview()

設置預覽類型
// 設置顯示類型
// 包含裁剪顯示, 原比例上下留黑顯示
mRecord.setFrame(mFrame)

錄制控制 /管理
切換攝像頭
mRecord.switchCamera()

獲取當前攝像頭
// 返回當前攝像頭 id
val facing = mRecord.getCameraFacing()
開關閃光燈
mRecord.flash(mFlash)

設置 zoom
// 設置焦距縮放, 0-100 100 為最大縮放
mRecord.setZoom(0)

設置曝光度
// 設置相機曝光度, 100 為最大曝光
mRecord.setExposureCompensation(0)

手動對焦
// 設置手動對焦, 參數為 x 和 y
mRecord.focus(mPointF)

設置錄制視頻的角度
/**
* @param rotation 旋轉角度包含 0 90 180 270
*/
mRecord.setRecordRotation(0)

設置靜音錄制
mRecord.setMute(false)

倍速錄制
/**
* @param speed 速度包含 0.25 0.5 1.0 2.0 4.0 倍速
*/
mRecord.setSpeed(mSpeed)

開始錄制
開始錄制一段視頻
/**
* 開始錄制一段視頻
* @param path 錄制的視頻保存的地址
* @param width 錄制視頻的寬, SDK 中會做 16 倍整數的運算, 可能最終輸出視頻的寬和設置進去的不一致
* @param height 錄制視頻的高, SDK 中會做 16 倍整數的運算, 可能最終輸出視頻的寬和設置進去的不一致
* @param videoBitRate 視頻輸出的碼率, 如果設置的是 2000, 則為 2M, 最終輸出的和設置的可能有差別
* @param frameRate 視頻輸出的幀率
* @param useHardWareEncode 是否使用硬編碼, 如果設置為 true, 而硬編碼不支持,則自動切換到軟編碼
* @param audioSampleRate 音頻的采樣率
* @param audioChannel 音頻的聲道數
* @param audioBitRate 音頻的碼率
* @param duration 需要錄制多少時間
* @return Int ErrorCode.SUCCESS 為成功,其它為失敗
* @throws InitRecorderFailException
*/
mRecord.startRecording("/sdcard/a.mp4", 720,1280,2000, // 2M 碼率 30, false, 44100, 1, // 單聲道 128, // 128K 碼率? Int.MAX_VALUE)

結束錄制
mRecord.stopRecording()

視頻編輯
初始化
創建編輯器實例
mVideoEditor = TrinityCore.createEditor(this)

設置預覽畫面
val surfaceView = findViewById<SurfaceView>(R.id.surface_view)
mVideoEditor.setSurfaceView(surfaceView)

導入視頻
添加一個片段
val clip = MediaClip(file.absolutePath)
mVideoEditor.insertClip(clip)

根據下標添加片段
val clip = MediaClip(file.absolutePath)
mVideoEditor.insertClip(0, clip)

刪除一個片段
/**
* 根據下標刪除一個片段
*/
mVideoEditor.removeClip(index)

獲取片段的數量
val count = mVideoEditor.getClipsCount()

根據下標獲取一個片段
/**
* 如果片段不存在, 返回一個 null
*/
val clip = mVideoEditor.getClip(index)

根據下標替換一個片段
mVideoEditor.replaceClip(index, clip)

獲取所有片段
/**
* 返回所有片段的集合
*/
val clips = mVideoEditor.getVideoClips()

獲取所有片段的時間總長
val duration = mVideoEditor.getVideoDuration()

獲取當前播放片段的進度
val current = mVideoEditor.getCurrentPosition()

獲取指定片段的開始和結束時間
val timeRange = mVideoEditor.getClipTimeRange(index)

根據時間查找片段的下標
val index = mVideoEditor.getClipIndex(time)

背景音樂
添加背景音樂
/**
* @param config 背景音樂 json 內容
* 具體 json 內容如下:
* {
*? ? "path": "/sdcard/trinity.mp3",
*? ? "startTime": 0,
*? ? "endTime": 2000
* }

* json 參數解釋:
* path: 音樂的本地地址
* startTime: 這個音樂的開始時間
* endTime: 這個音樂的結束時間 2000 代表這個音樂只播放 2 秒鐘
*/
val actionId = mVideoEditor.addMusic(config)

更新背景音樂
/**
* @param config 背景音樂 json 內容
* 具體 json 內容如下:
* {
*? ? "path": "/sdcard/trinity.mp3",
*? ? "startTime": 2000,
*? ? "endTime": 4000
* }
* json 參數解釋:
* path: 音樂的本地地址
* startTime: 這個音樂的開始時間
* endTime: 這個音樂的結束時間 4000 代表這個音樂從開始時間到結束時間播放 2 秒鐘
*/
val actionId = mVideoEditor.addMusic(config)

刪除背景音樂
/**
* 刪除背景音樂
* @param actionId 必須為添加背景音樂時返回的 actionId
*/
mVideoEditor.deleteMusic(actionId)

添加特效
添加普通濾鏡
/**
* 添加濾鏡
* 如: content.json 的絕對路徑為 /sdcard/Android/com.trinity.sample/cache/filters/config.json
* 傳入的路徑只需要 /sdcard/Android/com.trinity.sample/cache/filters 即可
* 如果當前路徑不包含 config.json 則添加失敗
* 具體 json 內容如下:
* {
*? "type": 0,
*? "intensity": 1.0,
*? "lut": "lut_124/lut_124.png"
* }
*
* json 參數解釋:
* type: 保留字段, 目前暫無作用
* intensity: 濾鏡透明度, 0.0 時和攝像頭采集的無差別
* lut: 濾鏡顏色表的地址, 必須為本地地址, 而且為相對路徑
*? ? ? sdk 內部會進行路徑拼接
* @param configPath 濾鏡 config.json 的父目錄
* @return 返回當前濾鏡的唯一 id
*/
val actionId = mVideoEditor.addFilter(config)

更新濾鏡
/**
* 更新濾鏡
* @param configPath config.json 的路徑, 目前對稱 addFilter 說明
* @param startTime 濾鏡的開始時間
* @param endTime 濾鏡的結束時間
* @param actionId 需要更新哪個濾鏡, 必須為 addFilter 返回的 actionId
*/
mVideoEditor.updateFilter(config, 0, 2000, actionId)

刪除濾鏡
/**
?* 刪除濾鏡
* @param actionId 需要刪除哪個濾鏡, 必須為 addFilter 時返回的 actionId
*/
mVideoEditor.deleteFilter(actionId)?

添加抖音特效
/**
* 添加特效
* 如: content.json 的絕對路徑為 /sdcard/Android/com.trinity.sample/cache/effects/config.json
* 傳入的路徑只需要 /sdcard/Android/com.trinity.sample/cache/effects 即可
* 如果當前路徑不包含 config.json 則添加失敗
* @param configPath 濾鏡 config.json 的父目錄
* @return 返回當前特效的唯一 id
*/
val actionId = mVideoEditor.addAction(configPath)

更新抖音特效
/**
* 更新指定特效
* @param startTime 特效的開始時間
* @param endTime 特效的結束時間
* @param actionId 需要更新哪個特效, 必須為 addAction 返回的 actionId
*/
mVideoEditor.updateAction(0, 2000, actionId)

刪除抖音特效
/**
* 刪除一個特效
* @param actionId 需要刪除哪個特效, 必須為 addAction 返回的 actionId
*/
mVideoEditor.deleteAction(actionId)

開始預覽
播放
/**

* @param repeat 是否循環播放

*/

mVideoEditor.play(repeat)

暫停

mVideoEditor.pause()

繼續播放

mVideoEditor.resume()

停止播放

mVideoEditor.stop()

釋放資源

mVideoEditor.destroy()

導出視頻

創建導出實例

val export = TrinityCore.createExport(this)

開始導出

/**

? * 開始導出

? * @param info 導出實體類

? * @param l 導出回調 包含成功 失敗 和進度回調

? * @return Int ErrorCode.SUCCESS 為成功,其它為失敗

? */

// 創建實體類, 必須傳入視頻輸出地址?

val exportVideoInfo = VideoExportInfo("/sdcard/export.mp4")

// 使用硬解碼

exportVideoInfo.mediaCodecDecode = true

// 使用硬編碼

exportVideoInfo.mediaCodecEncode = true?

// 視頻寬

exportVideoInfo.width = 544

// 視頻高

exportVideoInfo.height = 960

// 幀率

exportVideoInfo.frameRate = 25

// 視頻碼率 2M

exportVideoInfo.videoBitRate = 2000

// 采樣率

exportVideoInfo.sampleRate = 44100

// 聲道數

exportVideoInfo.channelCount = 1

// 音頻碼率 128K

exportVideoInfo.audioBitRate = 128

export.export(exportVideoInfo, this)

取消

export.cancel()

釋放

export.release()


轉載 *** https://v2ex.com/t/673557#reply0

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,546評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,570評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,505評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,017評論 1 313
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,786評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,219評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,287評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,438評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,971評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,796評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,995評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,540評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,230評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,918評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,697評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374