我想创建一个android应用程序,它可以找到一个视频文件(它超过300 MB)并将其压缩到较小的mp4文件。使用FFMPEG和JNI压缩视频
我已经尝试过用this
你既然压缩小尺寸的视频(以下超过100 MB)
所以我试图使用JNI来实现它本教程是一个非常有效的做到这一点。
我管理使用this
,但目前我想要做的是压缩视频打造的ffmpeg。我对JNI没有很好的了解。但是,我尝试使用以下link
去了解它。如果有人能指导我压缩使用JNI它打开的文件,真正对子级很好,谢谢
我想创建一个android应用程序,它可以找到一个视频文件(它超过300 MB)并将其压缩到较小的mp4文件。使用FFMPEG和JNI压缩视频
我已经尝试过用this
你既然压缩小尺寸的视频(以下超过100 MB)
所以我试图使用JNI来实现它本教程是一个非常有效的做到这一点。
我管理使用this
,但目前我想要做的是压缩视频打造的ffmpeg。我对JNI没有很好的了解。但是,我尝试使用以下link
去了解它。如果有人能指导我压缩使用JNI它打开的文件,真正对子级很好,谢谢
假设你已经得到的字符串路径后,视频的步骤输入文件,我们可以很容易地完成你的任务。我假设你已经理解了NDK的基础知识:如何在相应的.java文件中将本地.c文件连接到native
方法(让我知道这是否是你问题的一部分)。相反,我会专注于如何在Android/JNI的上下文中使用FFmpeg。
高度概括:
#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功能的全部内容(那些在驼峰),见Github我的全部项目。有问题吗?我很乐意详细说明。
我会尝试一下,让你知道,你可以给我你的邮件地址, –
我已经从GIT下载你的示例应用程序,但它似乎只适用于Android 4.4 –
作为你说我知道“如何将原生.c文件连接到相应的.java文件中的本地方法”我想知道压缩视频的本地C代码,我试图执行ut Github项目,但它似乎可以在android 4.4上工作 –
你说这个教程对于小尺寸视频非常有效。那么当您对大视频采取同样的措施时,是否还有任何问题? –
@AndroSelva是的,其实它的设备导向 –