如何使用Java/Kotlin在Android上减小视频文件大小?

9

我想在Android Studio中减小视频大小,并且为了上传到PlayStore需要兼容64位架构,之前尝试过使用ffmpeg成功地压缩了mp4,但花费的时间较长,而使用3gp格式的解决方案则不包括音频。是否有其他选项或库可以同时压缩带有音视频的mp4和3gp呢?

3个回答

2
您可能希望使用以下库,目前该库正在积极维护,并可帮助处理最新的Android API。

https://github.com/AbedElazizShe/LightCompressor

使用方法如下(Java)

implementation 'com.github.AbedElazizShe:LightCompressor:1.1.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3'


public static void compressVideo(Context context,
                                  Activity activity,
                                  ArrayList<Uri> videoUris) {


    VideoCompressor.start(context,
                          // => This is required
                          videoUris,
                          // => Source can be provided as content uris
                          true,
                          // => isStreamable
                          Environment.DIRECTORY_MOVIES,
                          // => the directory to save the compressed video(s)
                          new CompressionListener() {
                              @Override
                              public void onSuccess(int i,
                                                    long l,
                                                    @org.jetbrains.annotations.Nullable String s) {

                                  // On Compression success
                                  Log.d("TAG",
                                        "videoCompress i: " +i);

                                  Log.d("TAG",
                                        "videoCompress l: " +l);

                                  Log.d("TAG",
                                        "videoCompress s: " +s);

                              }

                              @Override
                              public void onStart(int i) {

                                  // Compression start

                              }

                              @Override
                              public void onFailure(int index,
                                                    String failureMessage) {
                                  // On Failure
                              }

                              @Override
                              public void onProgress(int index,
                                                     float progressPercent) {
                                  // Update UI with progress value
                                  activity.runOnUiThread(new Runnable() {
                                      public void run() {
                                      }
                                  });
                              }

                              @Override
                              public void onCancelled(int index) {
                                  // On Cancelled
                              }
                          },
                          new Configuration(VideoQuality.LOW,
                                            24, /*frameRate: int, or null*/
                                            false, /*isMinBitrateCheckEnabled*/
                                            null, /*videoBitrate: int, or null*/
                                            false, /*disableAudio: Boolean, or null*/
                                            false, /*keepOriginalResolution: Boolean, or null*/
                                            360.0, /*videoWidth: Double, or null*/
                                            480.0 /*videoHeight: Double, or null*/));

}

配置值

VideoQuality: VERY_HIGH (original-bitrate * 0.6) , HIGH (original-bitrate * 0.4), MEDIUM (original-bitrate * 0.3), LOW (original-bitrate * 0.2), OR VERY_LOW (original-bitrate * 0.1)

isMinBitrateCheckEnabled: this means, don't compress if bitrate is less than 2mbps

frameRate: any fps value

videoBitrate: any custom bitrate value

disableAudio: true/false to generate a video without audio. False by default.

keepOriginalResolution: true/false to tell the library not to change the resolution.

videoWidth: custom video width.

videoHeight: custom video height.

需要API级别21或更高 - Ezequiel Adrian

2

这里有另一个视频压缩库。该库可以在低、中和高质量下压缩视频。以下是使用示例:

VideoCompress.compressVideoMedium("/storage/emulated/0/Movies/source.mp4",
        "/storage/emulated/0/Movies/Compressed/compressed.mp4",
        new VideoCompress.CompressListener() {

    @Override
    public void onStart() {
        // Compression is started.
    }

    @Override
    public void onSuccess() {
        // Compression is successfully finished.
    }

    @Override
    public void onFail() {
        // Compression is failed.
    }

    @Override
    public void onProgress(float percent) {
        // Compression is in progress.
    }
});

1
这个库在转换时会丢失音频。 - Gibolt
1
这个视频压缩器有什么依赖关系?我从你给的链接中没有找到依赖项。 - John dahat
1
@Johndahat,不幸的是,这个库不在Maven或其他仓库中。但是该项目有一个名为videocompressor的Gradle模块,它就是库本身。您可以从那里复制源代码。这里是源代码的路径。 - Yamashiro Rion
有什么解决方案,为什么压缩视频后会丢失音频? - Prince Dholakiya

1
你可以使用这个库来实现:https://github.com/tcking/GiraffeCompressor

GiraffeCompressor.init(context);


//step 4: using compressor

GiraffeCompressor.create() //two implementations: mediacodec and ffmpeg,default is mediacodec
                  .input(inputFile) //set video to be compressed
                  .output(outputFile) //set compressed video output
                  .bitRate(bitRate)//set bitrate 码率
                  .resizeFactor(Float.parseFloat($.id(R.id.et_resize_factor).text()))//set video resize factor 分辨率缩放,默认保持原分辨率
                  .watermark("/sdcard/videoCompressor/watermarker.png")//add watermark(take a long time) 水印图片(需要长时间处理)
                  .ready()
                  .observeOn(AndroidSchedulers.mainThread())
                  .subscribe(new Subscriber<GiraffeCompressor.Result>() {
                      @Override
                      public void onCompleted() {
                          $.id(R.id.btn_start).enabled(true).text("start compress");
                      }

                      @Override
                      public void onError(Throwable e) {
                          e.printStackTrace();
                          $.id(R.id.btn_start).enabled(true).text("start compress");
                          $.id(R.id.tv_console).text("error:"+e.getMessage());

                      }

                      @Override
                      public void onNext(GiraffeCompressor.Result s) {
                          String msg = String.format("compress completed \ntake time:%s \nout put file:%s", s.getCostTime(), s.getOutput());
                          msg = msg + "\ninput file size:"+ Formatter.formatFileSize(getApplication(),inputFile.length());
                          msg = msg + "\nout file size:"+ Formatter.formatFileSize(getApplication(),new File(s.getOutput()).length());
                          System.out.println(msg);
                          $.id(R.id.tv_console).text(msg);
                      }
                  })

1
嗨。感谢您的评论,我之前尝试过Giraffe Compressor,但是为了上传到PlayStore,需要兼容64位架构。现在,我已经更新了我的问题,抱歉。 - Pablo DbSys
@PabloDbSys 你试过这个吗:https://stackoverflow.com/a/40861147/12053756 - Jagar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接