1
1
package net.kibotu.androidffmpegtranscoder.demo
2
2
3
- import android.Manifest
4
3
import android.content.Context
5
4
import android.net.Uri
6
5
import android.os.Bundle
7
6
import android.util.Log
8
7
import androidx.appcompat.app.AppCompatActivity
9
8
import androidx.core.view.isVisible
10
- import net.kibotu.androidffmpegtranscoder.mcvideoeditor.MediaCodecTranscoder
11
- import net.kibotu.androidffmpegtranscoder.mcvideoeditor.MediaConfig
12
- import net.kibotu.androidffmpegtranscoder.ffmpeg.EncodingConfig
13
- import net.kibotu.androidffmpegtranscoder.ffmpeg.FFMpegTranscoder
14
- import net.kibotu.androidffmpegtranscoder.ffmpeg.Progress
15
9
import io.reactivex.android.schedulers.AndroidSchedulers
16
10
import io.reactivex.disposables.CompositeDisposable
17
11
import io.reactivex.schedulers.Schedulers
18
12
import net.kibotu.androidffmpegtranscoder.demo.databinding.ActivityMainBinding
19
- import net.kibotu.androidffmpegtranscoder.demo.permissions.RxPermissions
13
+ import net.kibotu.androidffmpegtranscoder.ffmpeg.EncodingConfig
14
+ import net.kibotu.androidffmpegtranscoder.ffmpeg.FFMpegTranscoder
15
+ import net.kibotu.androidffmpegtranscoder.ffmpeg.Progress
16
+ import net.kibotu.androidffmpegtranscoder.mcvideoeditor.MediaCodecTranscoder
17
+ import net.kibotu.androidffmpegtranscoder.mcvideoeditor.MediaConfig
20
18
import net.kibotu.logger.Logger
21
19
import net.kibotu.logger.TAG
22
20
import java.io.File
@@ -26,42 +24,28 @@ import kotlin.math.roundToInt
26
24
27
25
28
26
class FFmpegActivity : AppCompatActivity () {
29
-
30
- private lateinit var binding : ActivityMainBinding
27
+
28
+ private lateinit var binding: ActivityMainBinding
31
29
32
30
var subscription: CompositeDisposable = CompositeDisposable ()
33
31
34
32
override fun onCreate (savedInstanceState : Bundle ? ) {
35
33
super .onCreate(savedInstanceState)
36
34
binding = ActivityMainBinding .inflate(layoutInflater)
37
35
setContentView(binding.root)
38
-
39
- checkWriteExternalStoragePermission()
36
+ run ()
40
37
}
41
38
42
39
// region location permission
43
40
44
- protected fun checkWriteExternalStoragePermission () {
45
- RxPermissions (this )
46
- .requestEachCombined(
47
- Manifest .permission.WRITE_EXTERNAL_STORAGE
48
- )
49
- .subscribe({
50
- if (it.granted)
51
- onWritePermissionGranted()
52
- }, {
53
- Logger .v(" permission $it " )
54
- })
55
- .addTo(subscription)
56
- }
41
+ private fun run () {
57
42
58
- private fun onWritePermissionGranted () {
43
+ binding.initFfmpeg.text =
44
+ " FFmpeg is ${if (FFMpegTranscoder .isSupported(this )) " " else " not" } supported."
59
45
60
- binding.initFfmpeg.text = " FFmpeg is ${if (FFMpegTranscoder .isSupported(this )) " " else " not" } supported."
61
-
62
- val frameFolder = " Download/process/" .parseExternalStorageFile()
63
- val inputVideo = " Download/walkaround.mp4" .parseExternalStorageFile()
64
- val outputVideo = " Download/stabilizedOutput_${System .currentTimeMillis()} .mp4" .parseExternalStorageFile()
46
+ val frameFolder = " transcoding/process" .parseInternalStorageFile(this )
47
+ val inputVideo = " input/source_video.mp4" .parseInternalStorageFile(this )
48
+ val outputVideo = " transcoding/output/output_${System .currentTimeMillis()} .mp4" .parseInternalStorageFile(this )
65
49
66
50
extractFrames(inputVideo, frameFolder)
67
51
@@ -76,11 +60,11 @@ class FFmpegActivity : AppCompatActivity() {
76
60
}
77
61
78
62
binding.deleteFolder.setOnClickListener {
79
- Logger .v(" delete folder = ${FFMpegTranscoder .deleteExtractedFrameFolder(frameFolder)} " )
63
+ Logger .v(" delete folder = ${FFMpegTranscoder .deleteExtractedFrameFolder(frameFolder)} " )
80
64
}
81
65
82
66
binding.deleteAll.setOnClickListener {
83
- Logger .v( " delete all = ${FFMpegTranscoder .deleteAllProcessFiles(this )} " )
67
+ Logger .v(" delete all = ${FFMpegTranscoder .deleteAllProcessFiles(this )} " )
84
68
}
85
69
}
86
70
@@ -97,15 +81,16 @@ class FFmpegActivity : AppCompatActivity() {
97
81
extractFramesProgress.isVisible = true
98
82
extractFramesProgress.setProgress(it.progress)
99
83
100
- Logger .v( " Analyze $it " )
84
+ Logger .v(" Analyze $it " )
101
85
102
- output.text = " ${(it.duration / 1000f ).roundToInt()} s ${it.message?.trimMargin()} \n ${output.text} "
86
+ output.text =
87
+ " ${(it.duration / 1000f ).roundToInt()} s ${it.message?.trimMargin()} \n ${output.text} "
103
88
104
89
}, {
105
- Logger .v( " transcode fails ${it.message} " )
90
+ Logger .v(" transcode fails ${it.message} " )
106
91
it.printStackTrace()
107
92
}, {
108
- Logger .v( " transcode on complete " )
93
+ Logger .v(" transcode on complete " )
109
94
110
95
FFMpegTranscoder .stabilize(
111
96
context = this @FFmpegActivity,
@@ -116,17 +101,18 @@ class FFmpegActivity : AppCompatActivity() {
116
101
.observeOn(AndroidSchedulers .mainThread())
117
102
.subscribe({
118
103
119
- extractFramesProgress.isVisible = true
104
+ extractFramesProgress.isVisible = true
120
105
extractFramesProgress.setProgress(it.progress)
121
106
122
- Logger .v( " Stabilize $it " )
107
+ Logger .v(" Stabilize $it " )
123
108
124
- output.text = " ${(it.duration / 1000f ).roundToInt()} s ${it.message?.trimMargin()} \n ${output.text} "
109
+ output.text =
110
+ " ${(it.duration / 1000f ).roundToInt()} s ${it.message?.trimMargin()} \n ${output.text} "
125
111
126
112
}, {
127
- Logger .v( " transcode fails ${it.message} " )
113
+ Logger .v(" transcode fails ${it.message} " )
128
114
it.printStackTrace()
129
- }, { Logger .v( " transcode on complete " ) })
115
+ }, { Logger .v(" transcode on complete " ) })
130
116
.addTo(subscription)
131
117
})
132
118
.addTo(subscription)
@@ -136,7 +122,7 @@ class FFmpegActivity : AppCompatActivity() {
136
122
137
123
private fun extractFrames (inputVideo : Uri , frameFolder : Uri ) {
138
124
139
- Logger .v( " uri=${inputVideo.assetFileExists} " )
125
+ Logger .v(" uri=${inputVideo.assetFileExists} " )
140
126
141
127
binding.extractFrames.setOnClickListener {
142
128
@@ -146,8 +132,10 @@ class FFmpegActivity : AppCompatActivity() {
146
132
increment * it.toDouble()
147
133
}
148
134
149
-
150
- extractByFFMpeg(inputVideo,frameFolder) // Uri.parse(copyAssetFileToCache("walkaround.mp4")!!.path)
135
+ extractByFFMpeg(
136
+ inputVideo,
137
+ frameFolder
138
+ ) // Uri.parse(copyAssetFileToCache("walkaround.mp4")!!.path)
151
139
// extactByMediaCodec(times, inputVideo, frameFolder)
152
140
153
141
}
@@ -156,16 +144,16 @@ class FFmpegActivity : AppCompatActivity() {
156
144
private fun mergeFrames (frameFolder : Uri , outputVideo : Uri ) {
157
145
158
146
binding.makeVideo.setOnClickListener {
159
- mergeByFFMpeg(frameFolder,outputVideo)
147
+ mergeByFFMpeg(frameFolder, outputVideo)
160
148
// mergeByMediaCodec(frameFolder, outputVideo)
161
149
}
162
150
}
163
151
164
152
private fun transcode (inputVideo : Uri , outputVideo : Uri ) {
165
153
166
- binding.transcodeVideo.setOnClickListener() {
154
+ binding.transcodeVideo.setOnClickListener {
167
155
168
- Logger .v( " transcode $inputVideo -> $outputVideo " )
156
+ Logger .v(" transcode $inputVideo -> $outputVideo " )
169
157
170
158
binding.output.text = " "
171
159
@@ -177,20 +165,20 @@ class FFmpegActivity : AppCompatActivity() {
177
165
.observeOn(AndroidSchedulers .mainThread())
178
166
.subscribe({
179
167
180
- Logger .v( " transcode $it " )
168
+ Logger .v(" transcode $it " )
181
169
182
170
}, {
183
- Logger .v( " transcode fails ${it.message} " )
171
+ Logger .v(" transcode fails ${it.message} " )
184
172
it.printStackTrace()
185
- }, { Logger .v( " transcode on complete " ) })
173
+ }, { Logger .v(" transcode on complete " ) })
186
174
.addTo(subscription)
187
175
}
188
176
}
189
177
190
178
// region ffmpeg
191
179
192
180
private fun extractByFFMpeg (inputVideo : Uri , frameFolder : Uri ) {
193
- Logger .v( " extractFramesFromVideo $inputVideo -> $frameFolder " )
181
+ Logger .v(" extractFramesFromVideo $inputVideo -> $frameFolder " )
194
182
195
183
val increment = 63f / 120f
196
184
@@ -200,31 +188,36 @@ class FFmpegActivity : AppCompatActivity() {
200
188
201
189
binding.output.text = " "
202
190
203
- FFMpegTranscoder .extractFramesFromVideo(context = this , frameTimes = times.map { it.toString() }, inputVideo = inputVideo, id = " 12345" , outputDir = frameFolder)
191
+ FFMpegTranscoder .extractFramesFromVideo(
192
+ context = this ,
193
+ frameTimes = times.map { it.toString() },
194
+ inputVideo = inputVideo,
195
+ id = " 12345" ,
196
+ outputDir = frameFolder
197
+ )
204
198
.subscribeOn(Schedulers .io())
205
199
.observeOn(AndroidSchedulers .mainThread())
206
200
.subscribe({
207
201
208
202
binding.extractFramesProgress.isVisible = true
209
203
binding.extractFramesProgress.setProgress(it.progress)
210
204
211
- Logger .v( " extract frames $it " )
212
-
213
- binding.output.text = " ${(it.duration / 1000f ).roundToInt()} s ${it.message?.trimMargin()} \n ${binding.output.text} "
214
-
205
+ Logger .v(" extract frames $it " )
215
206
207
+ binding.output.text =
208
+ " ${(it.duration / 1000f ).roundToInt()} s ${it.message?.trimMargin()} \n ${binding.output.text} "
216
209
}, {
217
- Logger .v( " extracting frames fail ${it.message} " )
210
+ Logger .v(" extracting frames fail ${it.message} " )
218
211
219
212
it.printStackTrace()
220
213
}, {
221
- Logger .v( " extractFramesFromVideo on complete" )
214
+ Logger .v(" extractFramesFromVideo on complete" )
222
215
})
223
216
.addTo(subscription)
224
217
}
225
218
226
219
private fun mergeByFFMpeg (frameFolder : Uri , outputVideo : Uri ) {
227
- Logger .v( " mergeFrames $frameFolder -> $outputVideo " )
220
+ Logger .v(" mergeFrames $frameFolder -> $outputVideo " )
228
221
229
222
binding.output.text = " "
230
223
@@ -243,13 +236,14 @@ class FFmpegActivity : AppCompatActivity() {
243
236
binding.mergeFramesProgress.isVisible = true
244
237
binding.mergeFramesProgress.setProgress(it.progress)
245
238
246
- Logger .v( " extract frames $it " )
239
+ Logger .v(" extract frames $it " )
247
240
248
- binding.output.text = " ${(it.duration / 1000f ).roundToInt()} s ${it.message?.trimMargin()} \n ${binding.output.text} "
241
+ binding.output.text =
242
+ " ${(it.duration / 1000f ).roundToInt()} s ${it.message?.trimMargin()} \n ${binding.output.text} "
249
243
250
244
}, {
251
- Logger .v( " creating video fails ${it.message} " )
252
- }, { Logger .v( " createVideoFromFrames on complete " ) })
245
+ Logger .v(" creating video fails ${it.message} " )
246
+ }, { Logger .v(" createVideoFromFrames on complete " ) })
253
247
.addTo(subscription)
254
248
}
255
249
// endregion
@@ -305,15 +299,16 @@ class FFmpegActivity : AppCompatActivity() {
305
299
binding.mergeFramesProgress.isVisible = true
306
300
binding.mergeFramesProgress.setProgress(it.progress)
307
301
308
- Logger .v( " merge frames $it " )
302
+ Logger .v(" merge frames $it " )
309
303
310
- binding.output.text = " ${(it.duration / 1000f ).roundToInt()} s ${it.message?.trimMargin()} \n ${binding.output.text} "
304
+ binding.output.text =
305
+ " ${(it.duration / 1000f ).roundToInt()} s ${it.message?.trimMargin()} \n ${binding.output.text} "
311
306
312
307
}, {
313
- Logger .v( " creating video fails ${it.message} " )
308
+ Logger .v(" creating video fails ${it.message} " )
314
309
315
310
}, {
316
- Logger .v( " createVideoFromFrames on complete " )
311
+ Logger .v(" createVideoFromFrames on complete " )
317
312
})
318
313
.addTo(subscription)
319
314
0 commit comments