Android 音频压缩功能之Ffmpeg

最近发现网上的压缩功能代码很多都是无法使用的,都是工具类的居多,安卓原生中实现音频压缩的案例搜索了很久还是没有从0到1很容易上手的博客。压缩本地音频的博客好少啊。

1.添加依赖,直接上代码:

implementation 'com.arthenica:mobile-ffmpeg-full-gpl:4.4.LTS'

import static com.arthenica.mobileffmpeg.Config.RETURN_CODE_SUCCESS;

import android.content.Context;
import android.os.Environment;

import com.alipay.pushsdk.util.log.LogUtil;
import com.arthenica.mobileffmpeg.ExecuteCallback;
import com.arthenica.mobileffmpeg.FFmpeg;

import java.io.File;
import java.io.FileNotFoundException;

/**
 * 录音文件转换器
 */
public class AudioConverter {
    private Context mContext;
    private File audioFile;
    private AudioFormat format;
    private ConversionCallback callback;

    private AudioConverter(Context context) {
        this.mContext = context;
    }

    public static AudioConverter with(Context context) {
        return new AudioConverter(context);
    }

    public AudioConverter setFile(File originalFile) {
        this.audioFile = originalFile;
        return this;
    }

    public AudioConverter setFormat(AudioFormat format) {
        this.format = format;
        return this;
    }

    public AudioConverter setCallback(ConversionCallback callback) {
        this.callback = callback;
        return this;
    }

    public void convert() {
        if (audioFile == null || format == null || callback == null) {
            throw new IllegalArgumentException("Incomplete conversion parameters.");
        }

        if (!audioFile.exists()) {
            callback.onConversionFailed(new FileNotFoundException("Audio file not found."));
            return;
        }

        // 输出音频地址1 android data 路径
//        File outputDirectory = mContext.getExternalFilesDir(Environment.DIRECTORY_MUSIC);
//        File outputFile = new File(outputDirectory, "output.mp3");
        // 输出音频地址2
        String path =  FileUtils.getVideoPath();
        File outputFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + path + "output.mp3");
        // 构建 FFmpeg 命令  FFMPEG 将 PCM 文件转换为 MP3 的示例代码
//        String command = String.format("-i %s -codec:a libmp3lame -qscale:a 2 %s", pcmFilePath, mp3FilePath);
        // -i input.mp3 -b:a 64k output.mp3
        // ffmpeg -i input.m4a -codec:a libmp3lame -qscale:a 2 output.mp3
        String[] command = getConversionCommand(audioFile.getAbsolutePath(), outputFile.getAbsolutePath(), format);
        String command2 = getConversionCommand2(audioFile.getAbsolutePath(), outputFile.getAbsolutePath());
        try {
//            Process exec = Runtime.getRuntime().exec("ffmpeg -i input.m4a -codec:a libmp3lame -qscale:a 2 output.mp3");
//            int code = exec.waitFor();
//            LogUtil.d("SGF", "---waitFor code---" + code);

//            FFmpeg.executeAsync("-i /storage/emulated/0/Record/Call/abc.m4a -b:a 64k " +  outputFile.getAbsolutePath(), new ExecuteCallback() {
            FFmpeg.executeAsync(command2, new ExecuteCallback() {
                @Override
                public void apply(final long executionId, final int returnCode) {
                    if (returnCode == RETURN_CODE_SUCCESS) {
                        callback.onConversionCompleted(outputFile.getAbsolutePath());
                    } else {
                        callback.onConversionFailed(new Exception("Conversion failed. Return code: " + returnCode));
                    }
                }
            });
        } catch (Exception e) {
            callback.onConversionFailed(e);
        }
    }

    private String[] getConversionCommand(String inputPath, String outputPath, AudioFormat format) {
        String audioCodec = format == AudioFormat.MP3 ? "libmp3lame" : "libfaac";
//        String[] command = {"-y", "-i", inputPath, "-c:a", audioCodec, outputPath};

        String[] command = {"-y", "-i", inputPath, "-c:a", audioCodec, outputPath};
//        String command = String.format("-i %s -codec:a libmp3lame -qscale:a 2 %s", inputPath, outputPath);
        return command;
    }

    private String getConversionCommand2(String inputPath, String outputPath) {
        return "-i " + inputPath + " -b:a 64k " + outputPath;
    }

    // 支持转换的类型:MP3, M4A,AAC,WMA,WAV,FLAC
    public enum AudioFormat {
        AMR,
        M4A,
        MP3
    }

    public interface ConversionCallback {
        void onConversionCompleted(String outputPath);

        void onConversionFailed(Exception exception);
    }
}

private void yaSuo(String path){
        showDialog();
        AudioConverter.ConversionCallback callback1 = new AudioConverter.ConversionCallback() {
            @Override
            public void onConversionCompleted(String outputPath) {
                hideDialog();
                LogUtil.d("SGF", "---onConversionCompleted---" + outputPath);
                ToastUtils.showShortToast(ctx, "压缩成功");
                stopTime();
                resetTime();
            }

            @Override
            public void onConversionFailed(Exception exception) {
                // 之前压缩的文件没有删除,会压缩失败
                hideDialog();
                stopTime();
                resetTime();
                LogUtil.d("SGF", "---onConversionFailed---" + exception.toString());
                ToastUtils.showShortToast(ctx, "压缩失败");
            }
        };

//        File file = new File("\"/storage/emulated/0/Record/Call/057110010 2025-05-2912-00-24.m4a\"");
//        File file = new File("/storage/emulated/0/Record/Call/abc.m4a");
        File file = new File(path);
        AudioConverter.with(this)
                .setFile(file) // Your current audio file
                .setFormat(AudioConverter.AudioFormat.MP3) // Your desired audio format
                .setCallback(callback1) // An callback to know when conversion is finished
                .convert(); // Start conversion
    }

public void startTime() {
//        tvTime.setBase(SystemClock.elapsedRealtime() - recordTime);//跳过已经记录的时间
        tvTime.setVisibility(View.VISIBLE);
        tvTime.setBase(SystemClock.elapsedRealtime());
        tvTime.setFormat("计时:%s");//设置显示的格式
        tvTime.start();
    }

    public void stopTime() {
        tvTime.stop();
        recordTime = SystemClock.elapsedRealtime() - tvTime.getBase();//保存这次记录的时间
    }

    public void resetTime() {
        tvTime.setVisibility(View.GONE);
        recordTime = 0;//重置时间
        tvTime.setBase(SystemClock.elapsedRealtime());
    }

@BindView(R.id.tv_time)
    Chronometer tvTime;

参考案例:

ffmpeg 命令行参数

使用FFmpeg压缩MP3格式音频

android 压缩本地音频文件

https://github.com/adrielcafe/AndroidAudioConverter

Android仿微信语音留言

Android 中使用 FFMPEG 将 PCM 音频采样转为 MP3 格式

android PCM音频压缩与传输

https://github.com/adrielcafe/AndroidAudioConverter

https://github.com/BillHoo/mobile-ffmpeg

Android FFmpeg压缩

你可能感兴趣的:(TEST,android,音视频,ffmpeg)