使用FFMPEG和JNI的COM preSS影片 [英] Compress Videos using FFMPEG and JNI

查看:218
本文介绍了使用FFMPEG和JNI的COM preSS影片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个Android应用程序,它可以找到一个视频文件(超过300 MB)和COM preSS它降低大小的MP4文件。

I want to create an android application which can locate a video file (which is more than 300 mb) and compress it to lower size mp4 file.

我已经尝试过用做这种

你既然COM pressing小尺寸的视频(以下超过100 MB)本教程是一个非常有效的

This tutorial is a very effective since you 're compressing a small size video (below than 100 mb)

所以,我试图用JNI来实现它。

So i tried to implement it using JNI .

我设法使用打造的ffmpeg

i managed to build ffmpeg using this

不过,目前我想要做的是COM preSS视频。我不想JNI有很好的了解。但我想了解它使用下面的<一个href="http://www.packtpub.com/sites/default/files/downloads/Developing_Multimedia_Applications_with_NDK.pdf">link

But currently what I want to do is to compress videos . I don't have very good knowledge on JNI. But i tried to understand it using following link

如果有人能指导我它使用JNI打开文件后,步骤COM preSS的视频是真的对子级伟大的,谢谢

If some one can guide me the steps to compress video after open file it using JNI that whould really great , thanks

推荐答案

假设你已经得到了输入文件的字符串路径,我们可以很容易的完成你的任务。我假设你有NDK基础知识的理解:如何将本地.c文件连接到本地方法,在相应的.java文件(让我知道这是一部分你的问题)。相反,我将重点介绍如何使用FFmpeg的安卓/ JNI的范围内。

Assuming you've got the String path of the input file, we can accomplish your task fairly easily. I'll assume you have an understanding of the NDK basics: How to connect a native .c file to native methods in a corresponding .java file (Let me know if that's part of your question). Instead I'll focus on how to use FFmpeg within the context of Android / JNI.

高级概述:

#include <jni.h>
#include <android/log.h>
#include <string.h>
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"

#define LOG_TAG "FFmpegWrapper"
#define LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)


void Java_com_example_yourapp_yourJavaClass_compressFile(JNIEnv *env, jobject obj, jstring jInputPath, jstring jInputFormat, jstring jOutputPath, jstring JOutputFormat){
  // One-time FFmpeg initialization
  av_register_all();
  avformat_network_init();
  avcodec_register_all();

  const char* inputPath = (*env)->GetStringUTFChars(env, jInputPath, NULL);
  const char* outputPath = (*env)->GetStringUTFChars(env, jOutputPath, NULL);
  // format names are hints. See available options on your host machine via $ ffmpeg -formats
  const char* inputFormat = (*env)->GetStringUTFChars(env, jInputFormat, NULL);
  const char* outputFormat = (*env)->GetStringUTFChars(env, jOutputFormat, NULL);

  AVFormatContext *outputFormatContext = avFormatContextForOutputPath(outputPath, outputFormat);
  AVFormatContext *inputFormatContext = avFormatContextForInputPath(inputPath, inputFormat /* not necessary since file can be inspected */);

  copyAVFormatContext(&outputFormatContext, &inputFormatContext);
  // Modify outputFormatContext->codec parameters per your liking
  // See http://ffmpeg.org/doxygen/trunk/structAVCodecContext.html

  int result = openFileForWriting(outputFormatContext, outputPath);
  if(result < 0){
      LOGE("openFileForWriting error: %d", result);
  }

  writeFileHeader(outputFormatContext);

  // Copy input to output frame by frame
  AVPacket *inputPacket;
  inputPacket = av_malloc(sizeof(AVPacket));

  int continueRecording = 1;
  int avReadResult = 0;
  int writeFrameResult = 0;
  int frameCount = 0;
  while(continueRecording == 1){
      avReadResult = av_read_frame(inputFormatContext, inputPacket);
      frameCount++;
      if(avReadResult != 0){
        if (avReadResult != AVERROR_EOF) {
            LOGE("av_read_frame error: %s", stringForAVErrorNumber(avReadResult));
        }else{
            LOGI("End of input file");
        }
        continueRecording = 0;
      }

      AVStream *outStream = outputFormatContext->streams[inputPacket->stream_index];
      writeFrameResult = av_interleaved_write_frame(outputFormatContext, inputPacket);
      if(writeFrameResult < 0){
          LOGE("av_interleaved_write_frame error: %s", stringForAVErrorNumber(avReadResult));
      }
  }

  // Finalize the output file
  int writeTrailerResult = writeFileTrailer(outputFormatContext);
  if(writeTrailerResult < 0){
      LOGE("av_write_trailer error: %s", stringForAVErrorNumber(writeTrailerResult));
  }
  LOGI("Wrote trailer");
}

有关的所有auxillary功能的全部内容(那些在驼峰),看到我在<一个完整的项目href="https://github.com/OnlyInAmerica/FFmpegTest/blob/365fdd214f5749400107924a91b23f1580244490/jni/FFmpegWrapper.c"相对=nofollow> Github上。你有问题?我很高兴来阐述。

For the full content of all the auxillary functions (the ones in camelCase), see my full project on Github. Got questions? I'm happy to elaborate.

这篇关于使用FFMPEG和JNI的COM preSS影片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆