Feature: extract audio waveform

pull/221/head
xufuji456 2 years ago
parent 6bba0d8692
commit 643d4c8081
  1. 2
      app/CMakeLists.txt
  2. 2
      app/src/main/cpp/video_cutting.cpp
  3. 0
      app/src/main/cpp/video_cutting.h
  4. 59
      app/src/main/java/com/frank/ffmpeg/activity/AudioHandleActivity.kt
  5. 9
      app/src/main/java/com/frank/ffmpeg/util/FFmpegUtil.java
  6. 15
      app/src/main/res/layout/activity_audio_handle.xml
  7. 2
      app/src/main/res/values-en/strings.xml
  8. 2
      app/src/main/res/values/strings.xml

@ -31,7 +31,7 @@ add_library( # Sets the name of the library.
src/main/cpp/ffmpeg_pusher.cpp src/main/cpp/ffmpeg_pusher.cpp
src/main/cpp/video_filter.c src/main/cpp/video_filter.c
src/main/cpp/ffprobe_cmd.cpp src/main/cpp/ffprobe_cmd.cpp
src/main/cpp/cut_video.cpp src/main/cpp/video_cutting.cpp
src/main/cpp/visualizer/fft.cpp src/main/cpp/visualizer/fft.cpp
src/main/cpp/visualizer/fixed_fft.cpp src/main/cpp/visualizer/fixed_fft.cpp
src/main/cpp/visualizer/block_queue.c src/main/cpp/visualizer/block_queue.c

@ -2,7 +2,7 @@
// Created by xu fulong on 2022/5/13. // Created by xu fulong on 2022/5/13.
// //
#include <cut_video.h> #include <video_cutting.h>
#ifdef __ANDROID__ #ifdef __ANDROID__
#include <android/log.h> #include <android/log.h>

@ -123,8 +123,8 @@ class AudioHandleActivity : BaseActivity() {
getString(R.string.audio_add_equalizer), getString(R.string.audio_add_equalizer),
getString(R.string.audio_silence), getString(R.string.audio_silence),
getString(R.string.audio_volume), getString(R.string.audio_volume),
getString(R.string.audio_encode), getString(R.string.audio_waveform),
getString(R.string.pcm_concat)) getString(R.string.audio_encode))
layoutAudioHandle = findViewById(R.id.list_audio_item) layoutAudioHandle = findViewById(R.id.list_audio_item)
val layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL) val layoutManager = StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL)
@ -181,8 +181,7 @@ class AudioHandleActivity : BaseActivity() {
} }
}.start() }.start()
} }
1 //cut audio, it's best not include special characters 1 -> { //cut audio, it's best not include special characters
-> {
val suffix = FileUtil.getFileSuffix(srcFile) val suffix = FileUtil.getFileSuffix(srcFile)
if (suffix == null || suffix.isEmpty()) { if (suffix == null || suffix.isEmpty()) {
return return
@ -190,16 +189,14 @@ class AudioHandleActivity : BaseActivity() {
outputPath = PATH + File.separator + "cutAudio" + suffix outputPath = PATH + File.separator + "cutAudio" + suffix
commandLine = FFmpegUtil.cutAudio(srcFile, 10.5f, 15.0f, outputPath) commandLine = FFmpegUtil.cutAudio(srcFile, 10.5f, 15.0f, outputPath)
} }
2 //concat audio 2 -> { //concat audio
-> {
if (!FileUtil.checkFileExist(appendFile)) { if (!FileUtil.checkFileExist(appendFile)) {
return return
} }
concatAudio(srcFile) concatAudio(srcFile)
return return
} }
3 //mix audio 3 -> { //mix audio
-> {
if (!FileUtil.checkFileExist(appendFile)) { if (!FileUtil.checkFileExist(appendFile)) {
return return
} }
@ -215,39 +212,33 @@ class AudioHandleActivity : BaseActivity() {
FFmpegUtil.mergeAudio(srcFile, appendFile, outputPath) FFmpegUtil.mergeAudio(srcFile, appendFile, outputPath)
} }
} }
4 //use AudioTrack to play audio 4 -> { //use AudioTrack to play audio
-> {
val audioIntent = Intent(this@AudioHandleActivity, AudioPlayActivity::class.java) val audioIntent = Intent(this@AudioHandleActivity, AudioPlayActivity::class.java)
audioIntent.data = Uri.parse(srcFile) audioIntent.data = Uri.parse(srcFile)
startActivity(audioIntent) startActivity(audioIntent)
return return
} }
5 //change audio speed 5 -> { //change audio speed
-> {
val speed = 2.0f // funny effect, range from 0.5 to 100.0 val speed = 2.0f // funny effect, range from 0.5 to 100.0
outputPath = PATH + File.separator + "speed.mp3" outputPath = PATH + File.separator + "speed.mp3"
commandLine = FFmpegUtil.changeAudioSpeed(srcFile, outputPath, speed) commandLine = FFmpegUtil.changeAudioSpeed(srcFile, outputPath, speed)
} }
6 //echo effect 6 -> { //echo effect
-> {
val echo = 1000 // echo effect, range from 0 to 90000 val echo = 1000 // echo effect, range from 0 to 90000
outputPath = PATH + File.separator + "echo.mp3" outputPath = PATH + File.separator + "echo.mp3"
commandLine = FFmpegUtil.audioEcho(srcFile, echo, outputPath) commandLine = FFmpegUtil.audioEcho(srcFile, echo, outputPath)
} }
7 //tremolo effect 7 -> { //tremolo effect
-> {
val frequency = 5 // range from 0.1 to 20000.0 val frequency = 5 // range from 0.1 to 20000.0
val depth = 0.9f // range from 0 to 1 val depth = 0.9f // range from 0 to 1
outputPath = PATH + File.separator + "tremolo.mp3" outputPath = PATH + File.separator + "tremolo.mp3"
commandLine = FFmpegUtil.audioTremolo(srcFile, frequency, depth, outputPath) commandLine = FFmpegUtil.audioTremolo(srcFile, frequency, depth, outputPath)
} }
8 //audio denoise 8 -> { //audio denoise
-> {
outputPath = PATH + File.separator + "denoise.mp3" outputPath = PATH + File.separator + "denoise.mp3"
commandLine = FFmpegUtil.audioDenoise(srcFile, outputPath) commandLine = FFmpegUtil.audioDenoise(srcFile, outputPath)
} }
9 // equalizer plus 9 -> { // equalizer plus
-> {
// key:band value:gain=[0-20] // key:band value:gain=[0-20]
val bandList = arrayListOf<String>() val bandList = arrayListOf<String>()
bandList.add("6b=5") bandList.add("6b=5")
@ -259,18 +250,20 @@ class AudioHandleActivity : BaseActivity() {
outputPath = PATH + File.separator + "equalize.mp3" outputPath = PATH + File.separator + "equalize.mp3"
commandLine = FFmpegUtil.audioEqualizer(srcFile, bandList, outputPath) commandLine = FFmpegUtil.audioEqualizer(srcFile, bandList, outputPath)
} }
10 //silence detect 10 -> { //silence detect
-> {
commandLine = FFmpegUtil.audioSilenceDetect(srcFile) commandLine = FFmpegUtil.audioSilenceDetect(srcFile)
} }
11 // modify volume 11 -> { // modify volume
-> {
val volume = 0.5f // 0.0-1.0 val volume = 0.5f // 0.0-1.0
outputPath = PATH + File.separator + "volume.mp3" outputPath = PATH + File.separator + "volume.mp3"
commandLine = FFmpegUtil.audioVolume(srcFile, volume, outputPath) commandLine = FFmpegUtil.audioVolume(srcFile, volume, outputPath)
} }
12 //audio encode 12 -> { // audio waveform
-> { outputPath = PATH + File.separator + "waveform.png"
val resolution = "1280x720"
commandLine = FFmpegUtil.showAudioWaveform(srcFile, resolution, outputPath)
}
13 -> { //audio encode
val pcmFile = PATH + File.separator + "raw.pcm" val pcmFile = PATH + File.separator + "raw.pcm"
outputPath= PATH + File.separator + "convert.mp3" outputPath= PATH + File.separator + "convert.mp3"
//sample rate, normal is 8000/16000/44100 //sample rate, normal is 8000/16000/44100
@ -279,20 +272,6 @@ class AudioHandleActivity : BaseActivity() {
val channel = 2 val channel = 2
commandLine = FFmpegUtil.encodeAudio(pcmFile, outputPath, sampleRate, channel) commandLine = FFmpegUtil.encodeAudio(pcmFile, outputPath, sampleRate, channel)
} }
13 //concat PCM streams
-> {
val srcPCM = PATH + File.separator + "audio.pcm"
val appendPCM = PATH + File.separator + "audio.pcm"
val concatPCM = PATH + File.separator + "concat.pcm"
if (!FileUtil.checkFileExist(srcPCM) || !FileUtil.checkFileExist(appendPCM)) {
return
}
mHandler.obtainMessage(MSG_BEGIN).sendToTarget()
FileUtil.concatFile(srcPCM, appendPCM, concatPCM)
mHandler.obtainMessage(MSG_FINISH).sendToTarget()
return
}
else -> { else -> {
} }
} }

@ -359,7 +359,7 @@ public class FFmpegUtil {
*/ */
public static String[] jointVideo(String fileListPath, String outputPath) { public static String[] jointVideo(String fileListPath, String outputPath) {
// ffmpeg -f concat -safe 0 -i %s -c copy %s // ffmpeg -f concat -safe 0 -i %s -c copy %s
String jointVideoCmd = "ffmpeg -f concat -safe 0 -i -c copy"; String jointVideoCmd = "ffmpeg -f concat -safe 0 -i file.txt -c copy %s";
return insert(jointVideoCmd.split(" "), 6, fileListPath, outputPath); return insert(jointVideoCmd.split(" "), 6, fileListPath, outputPath);
} }
@ -820,4 +820,11 @@ public class FFmpegUtil {
return insert(trimCmd.split(" "), 2, inputPath, outputPath); return insert(trimCmd.split(" "), 2, inputPath, outputPath);
} }
public static String[] showAudioWaveform(String inputPath, String resolution, String outputPath) {
String waveformCmd = "ffmpeg -i -filter_complex showwavespic=s=%s";
waveformCmd = String.format(Locale.getDefault(), waveformCmd, resolution);
return insert(waveformCmd.split(" "), 2, inputPath, outputPath);
}
// ffmpeg -i beyond.mp4 -vf stereo3d=sbsl:arbg -y left3d.mp4
} }

@ -64,14 +64,6 @@
android:layout_marginTop="10dp" android:layout_marginTop="10dp"
android:visibility="gone"/> android:visibility="gone"/>
<Button
android:id="@+id/btn_pcm_concat"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/pcm_concat"
android:layout_marginTop="10dp"
android:visibility="gone"/>
<Button <Button
android:id="@+id/btn_audio_speed" android:id="@+id/btn_audio_speed"
android:layout_width="wrap_content" android:layout_width="wrap_content"
@ -121,6 +113,13 @@
android:text="@string/audio_volume" android:text="@string/audio_volume"
android:layout_marginTop="10dp" /> android:layout_marginTop="10dp" />
<Button
android:id="@+id/btn_audio_waveform"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/audio_waveform"
android:layout_marginTop="10dp" />
</LinearLayout> </LinearLayout>
<include <include

@ -6,8 +6,8 @@
<string name="audio_mix">Audio mix</string> <string name="audio_mix">Audio mix</string>
<string name="audio_play">Audio play</string> <string name="audio_play">Audio play</string>
<string name="audio_opensl">OpenSL play</string> <string name="audio_opensl">OpenSL play</string>
<string name="audio_waveform">Waveform</string>
<string name="audio_encode">PCM encode</string> <string name="audio_encode">PCM encode</string>
<string name="pcm_concat">PCM concat</string>
<string name="audio_speed">Audio speed</string> <string name="audio_speed">Audio speed</string>
<string name="audio_echo">Echo effect</string> <string name="audio_echo">Echo effect</string>
<string name="audio_tremolo">Tremolo effect</string> <string name="audio_tremolo">Tremolo effect</string>

@ -6,8 +6,8 @@
<string name="audio_mix">音乐混音</string> <string name="audio_mix">音乐混音</string>
<string name="audio_play">音频播放</string> <string name="audio_play">音频播放</string>
<string name="audio_opensl">OpenSL播放</string> <string name="audio_opensl">OpenSL播放</string>
<string name="audio_waveform">波形图</string>
<string name="audio_encode">PCM编码</string> <string name="audio_encode">PCM编码</string>
<string name="pcm_concat">PCM合并</string>
<string name="audio_speed">音频速度</string> <string name="audio_speed">音频速度</string>
<string name="audio_echo">空灵效果</string> <string name="audio_echo">空灵效果</string>
<string name="audio_tremolo">惊悚效果</string> <string name="audio_tremolo">惊悚效果</string>

Loading…
Cancel
Save