Объединение видео и аудио -потоков с использованием библиотек FFMPEG в JNI - вывод видео BlackAndroid

Форум для тех, кто программирует под Android
Anonymous
Объединение видео и аудио -потоков с использованием библиотек FFMPEG в JNI - вывод видео Black

Сообщение Anonymous »

Я пытаюсь объединить видеофайл и аудиофайл в один MP4, используя библиотеки FFMPEG (LibavFormat, LibavCodec, Libavutil и т. Д.) через JNI на Android. < /p>
У меня уже загружены библиотеки. Вот упрощенная версия моего нативного метода: < /p>

Код: Выделить всё

#include 
#include 
#include 
#include 
#include 

#define TAG "Downloader"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)

JNIEXPORT jint JNICALL
Java_com_harrshbermann_SocialMate_Downloader_mergeAV(
JNIEnv *env,
jobject thiz,
jstring jVideoPath,
jstring jAudioPath,
jstring jOutPath) {

const char *videoPath = (*env)->GetStringUTFChars(env, jVideoPath, 0);
const char *audioPath = (*env)->GetStringUTFChars(env, jAudioPath, 0);
const char *outPath   = (*env)->GetStringUTFChars(env, jOutPath, 0);

avformat_network_init();

AVFormatContext *videoFmtCtx = NULL;
AVFormatContext *audioFmtCtx = NULL;
AVFormatContext *outFmtCtx   = NULL;

if (avformat_open_input(&videoFmtCtx, videoPath, NULL, NULL) < 0) return -1;
if (avformat_open_input(&audioFmtCtx, audioPath, NULL, NULL) < 0) return -2;

if (avformat_find_stream_info(videoFmtCtx, NULL) < 0 ||
avformat_find_stream_info(audioFmtCtx, NULL) < 0) return -3;

if (avformat_alloc_output_context2(&outFmtCtx, NULL, NULL, outPath) < 0 || !outFmtCtx) return -4;

// Video
AVStream *inVideo  = videoFmtCtx->streams[0];
AVStream *outVideo = avformat_new_stream(outFmtCtx, NULL);
avcodec_parameters_copy(outVideo->codecpar, inVideo->codecpar);
outVideo->time_base = inVideo->time_base;

// Copy extradata
if (inVideo->codecpar->extradata_size > 0) {
outVideo->codecpar->extradata = av_mallocz(inVideo->codecpar->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
memcpy(outVideo->codecpar->extradata,
inVideo->codecpar->extradata,
inVideo->codecpar->extradata_size);
outVideo->codecpar->extradata_size = inVideo->codecpar->extradata_size;
}

// Audio
AVStream *inAudio  = audioFmtCtx->streams[0];
AVStream *outAudio = avformat_new_stream(outFmtCtx, NULL);
avcodec_parameters_copy(outAudio->codecpar, inAudio->codecpar);
outAudio->time_base = inAudio->time_base;

if (inAudio->codecpar->extradata_size > 0) {
outAudio->codecpar->extradata = av_mallocz(inAudio->codecpar->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
memcpy(outAudio->codecpar->extradata,
inAudio->codecpar->extradata,
inAudio->codecpar->extradata_size);
outAudio->codecpar->extradata_size = inAudio->codecpar->extradata_size;
}

if (!(outFmtCtx->oformat->flags &  AVFMT_NOFILE)) {
avio_open(&outFmtCtx->pb, outPath, AVIO_FLAG_WRITE);
}

avformat_write_header(outFmtCtx, NULL);

// Copy video packets
AVPacket pkt;
while (av_read_frame(videoFmtCtx, &pkt) >= 0) {
AVStream *in_st  = videoFmtCtx->streams[pkt.stream_index];
AVStream *out_st = outVideo;

pkt.pts      = av_rescale_q(pkt.pts,  in_st->time_base, out_st->time_base);
pkt.dts      = av_rescale_q(pkt.dts,  in_st->time_base, out_st->time_base);
pkt.duration = av_rescale_q(pkt.duration, in_st->time_base, out_st->time_base);
pkt.pos      = -1;
pkt.stream_index = out_st->index;

av_interleaved_write_frame(outFmtCtx, &pkt);
av_packet_unref(&pkt);
}

// Copy audio packets
while (av_read_frame(audioFmtCtx, &pkt) >= 0) {
AVStream *in_st  = audioFmtCtx->streams[pkt.stream_index];
AVStream *out_st = outAudio;

pkt.pts      = av_rescale_q(pkt.pts,  in_st->time_base, out_st->time_base);
pkt.dts      = av_rescale_q(pkt.dts,  in_st->time_base, out_st->time_base);
pkt.duration = av_rescale_q(pkt.duration, in_st->time_base, out_st->time_base);
pkt.pos      = -1;
pkt.stream_index = out_st->index;

av_interleaved_write_frame(outFmtCtx, &pkt);
av_packet_unref(&pkt);
}

av_write_trailer(outFmtCtx);

avformat_close_input(&videoFmtCtx);
avformat_close_input(&audioFmtCtx);
if (!(outFmtCtx->oformat->flags & AVFMT_NOFILE)) avio_closep(&outFmtCtx->pb);
avformat_free_context(outFmtCtx);

(*env)->ReleaseStringUTFChars(env, jVideoPath, videoPath);
(*env)->ReleaseStringUTFChars(env, jAudioPath, audioPath);
(*env)->ReleaseStringUTFChars(env, jOutPath, outPath);

return 0;
}
Проблема:
Обключенный файл правильно воспроизводит звук, но видео просто черное. /> ffmpeg -i video.mp4 -i audio.m4a -c Copy output.mp4 < /p>
Вопрос: < /p>
Каков правильный способ слияния видео + аудио -потоки непосредственно с помощью mp4. Audio? I уже:
Загрузите все необходимые FFMPEG .SO Библиотеки
Открытые форматы ввода и выделять выходной контекст
Копировать параметры кодека с avcodec_parameters_copy
extradata
rescal Продолжительность < /p>
Чего мне не хватает, чтобы сделать видео воспроизводимым (вместо черного)?>

Подробнее здесь: https://stackoverflow.com/questions/797 ... -video-bla

Вернуться в «Android»