深度學(xué)習(xí)實(shí)戰(zhàn)》—3.8.2 怎么做">《Keras深度學(xué)習(xí)實(shí)戰(zhàn)》—3.8.2 怎么做
1233
2025-03-31
文章目錄
一、推薦開(kāi)源項(xiàng)目
二、Android 中執(zhí)行 FFMPEG 指令
1、導(dǎo)入依賴(lài)
2、Java 代碼編寫(xiě)
3、使用時(shí)的代碼示例
三、博客資源
一、推薦開(kāi)源項(xiàng)目
最近需要在 Android 中進(jìn)行音視頻數(shù)據(jù)轉(zhuǎn)碼 , 音頻混音 , 音頻編輯邊裁 等操作 , 如果能在 Android 系統(tǒng)中執(zhí)行 FFMPEG 指令 , 基本就可以晚上需求 ;
推薦一個(gè) GitHub 上的項(xiàng)目 : https://github.com/WritingMinds/ffmpeg-android-java
該項(xiàng)目中 FFmpegAndroid 是 Android Library 核心依賴(lài)庫(kù) , 在自己的項(xiàng)目中 , 引入該依賴(lài)庫(kù)即可進(jìn)行 FFMPEG 命令執(zhí)行 ;
app Module 僅僅是一個(gè)示例項(xiàng)目 , 展示 FFmpegAndroid 依賴(lài)庫(kù)如何使用 ;
在 FFmpegAndroid 項(xiàng)目中的
ffmpeg-android-java-0.3.2\FFmpegAndroid\assets\armeabi-v7a\ffmpeg
是 FFMPEG 可執(zhí)行文件 , 可以在 ARM 架構(gòu)的 Android 系統(tǒng)中執(zhí)行 ;
在
ffmpeg-android-java-0.3.2\FFmpegAndroid\assets\x86\ffmpeg
是可以在 x86 架構(gòu)的 Android 系統(tǒng)中可執(zhí)行的文件 ;
這個(gè) ffmpeg 可執(zhí)行文件是該應(yīng)用的核心 ;
基于最后一個(gè)可運(yùn)行版本進(jìn)行調(diào)試 ,
這個(gè)項(xiàng)目在 2016 2016 2016 年停止維護(hù)了 , 運(yùn)行后一堆報(bào)錯(cuò) , 引用了遠(yuǎn)古版本的 ButterKnife 和 Dagger 依賴(lài)庫(kù) , 更新了最新的 com.github.dcendents:android-maven-gradle-plugin 插件 , 然后添加了 google() 庫(kù)支持 , 項(xiàng)目運(yùn)行起來(lái)了 ;
參考 :
【錯(cuò)誤記錄】編譯安卓項(xiàng)目報(bào)錯(cuò) ( AndroidMavenPlugin 錯(cuò)誤 )
【錯(cuò)誤記錄】安卓編譯錯(cuò)誤 ( Could not find xxx.tools.build:aapt2 )
運(yùn)行該項(xiàng)目 , 執(zhí)行
-version
1
命令 , 打印出該 FFMPEG 的版本 , 3.0.1 的版本 , 有點(diǎn)老 ;
二、Android 中執(zhí)行 FFMPEG 指令
參考 http://writingminds.github.io/ffmpeg-android-java/ 博客中的使用介紹 ;
1、導(dǎo)入依賴(lài)
直接引用項(xiàng)目 :
repositories { flatDir { dirs 'libs' } } dependencies { compile(name:'FFmpegAndroid', ext:'aar') }
1
2
3
4
5
6
7
8
9
添加 Gradle 依賴(lài)庫(kù) :
compile 'com.writingminds:FFmpegAndroid:0.3.2'
1
Maven 依賴(lài)庫(kù) :
1
2
3
4
5
2、Java 代碼編寫(xiě)
首先 , 初始化 FFMPEG 實(shí)例 ;
FFmpeg ffmpeg = FFmpeg.getInstance(context);
1
然后 , 加載 ffmpeg 可執(zhí)行文件 , 該操作是將可執(zhí)行文件從 assets 目錄中拷貝到 Android 應(yīng)用的內(nèi)置存儲(chǔ)空間 ;
try { ffmpeg.loadBinary(new LoadBinaryResponseHandler() { @Override public void onStart() {} @Override public void onFailure() {} @Override public void onSuccess() {} @Override public void onFinish() {} }); } catch (FFmpegNotSupportedexception e) { // Handle if FFmpeg is not supported by device }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
最后 , 執(zhí)行 FFMPEG 命令 ;
try { // to execute "ffmpeg -version" command you just need to pass "-version" ffmpeg.execute(cmd, new ExecuteBinaryResponseHandler() { @Override public void onStart() {} @Override public void onProgress(String message) {} @Override public void onFailure(String message) {} @Override public void onSuccess(String message) {} @Override public void onFinish() {} }); } catch (FFmpegCommandAlreadyRunningexception e) { // Handle if FFmpeg is already running }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
3、使用時(shí)的代碼示例
ffmpeg-android-java 項(xiàng)目中 app 的主界面代碼 , 有上述 3 3 3 個(gè)完整的使用步驟 ;
package com.github.hiteshsondhi88.sampleffmpeg; import android.app.Activity; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.DialogInterface; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import com.github.hiteshsondhi88.libffmpeg.ExecuteBinaryResponseHandler; import com.github.hiteshsondhi88.libffmpeg.FFmpeg; import com.github.hiteshsondhi88.libffmpeg.LoadBinaryResponseHandler; import com.github.hiteshsondhi88.libffmpeg.exceptions.FFmpegCommandAlreadyRunningException; import com.github.hiteshsondhi88.libffmpeg.exceptions.FFmpegNotSupportedException; public class Home extends Activity implements View.OnClickListener { private static final String TAG = Home.class.getSimpleName(); FFmpeg ffmpeg; EditText commandEditText; LinearLayout outputLayout; Button runButton; private ProgressDialog progressDialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_home); // 1. 獲取 FFMPEG 實(shí)例 ffmpeg = FFmpeg.getInstance(this); commandEditText = (EditText) findViewById(R.id.command); outputLayout = (LinearLayout) findViewById(R.id.command_output); runButton = (Button) findViewById(R.id.run_command); loadFFMpegBinary(); initUI(); } private void initUI() { runButton.setOnClickListener(this); progressDialog = new ProgressDialog(this); progressDialog.setTitle(null); } // 2. 加載 ffmpeg 可執(zhí)行文件 private void loadFFMpegBinary() { try { ffmpeg.loadBinary(new LoadBinaryResponseHandler() { @Override public void onFailure() { showUnsupportedExceptionDialog(); } }); } catch (FFmpegNotSupportedException e) { showUnsupportedExceptionDialog(); } } // 3. 執(zhí)行命令 private void execFFmpegBinary(final String[] command) { try { ffmpeg.execute(command, new ExecuteBinaryResponseHandler() { @Override public void onFailure(String s) { addTextViewToLayout("FAILED with output : "+s); } @Override public void onSuccess(String s) { addTextViewToLayout("SUCCESS with output : "+s); } @Override public void onProgress(String s) { Log.d(TAG, "Started command : ffmpeg "+command); addTextViewToLayout("progress : "+s); progressDialog.setMessage("Processing\n"+s); } @Override public void onStart() { outputLayout.removeAllViews(); Log.d(TAG, "Started command : ffmpeg " + command); progressDialog.setMessage("Processing..."); progressDialog.show(); } @Override public void onFinish() { Log.d(TAG, "Finished command : ffmpeg "+command); progressDialog.dismiss(); } }); } catch (FFmpegCommandAlreadyRunningException e) { // do nothing for now } } private void addTextViewToLayout(String text) { TextView textView = new TextView(Home.this); textView.setText(text); outputLayout.addView(textView); } private void showUnsupportedExceptionDialog() { new AlertDialog.Builder(Home.this) .setIcon(android.R.drawable.ic_dialog_alert) .setTitle(getString(R.string.device_not_supported)) .setMessage(getString(R.string.device_not_supported_message)) .setCancelable(false) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Home.this.finish(); } }) .create() .show(); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.run_command: String cmd = commandEditText.getText().toString(); String[] command = cmd.split(" "); if (command.length != 0) { execFFmpegBinary(command); } else { Toast.makeText(Home.this, getString(R.string.empty_command_toast), Toast.LENGTH_LONG).show(); } break; } } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
三、博客資源
調(diào)試通過(guò)的源碼- : https://download.csdn.net/download/han1202012/19156661
資源內(nèi)容 : 源碼 , FFMPEG 中文文檔 ;
Android ARM
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶(hù)投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。
版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶(hù)投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。