Verschmelzung von Video- und Audio -Streams mit FFMPEG -Bibliotheken in JNI - Ausgabe Video Black

Post a reply

Smilies
:) :( :oops: :chelo: :roll: :wink: :muza: :sorry: :angel: :read: *x) :clever:
View more smilies

BBCode is ON
[img] is ON
[flash] is OFF
[url] is ON
Smilies are ON

Topic review
   

Expand view Topic review: Verschmelzung von Video- und Audio -Streams mit FFMPEG -Bibliotheken in JNI - Ausgabe Video Black

by Anonymous » 14 Sep 2025, 23:20

Ich versuche, eine Videodatei und eine Audiodatei in einen einzigen MP4 mit FFMPEG -Bibliotheken (libavformat, libavcodec, libavutil usw.) über JNI on Android zu verschmelzen. Hier ist der vereinfachte Ansatz, den ich verwende: < /p>

Code: Select all

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;

LOGD("Opening video file: %s", videoPath);
LOGD("Opening audio file: %s", audioPath);
LOGD("Output path: %s", outPath);

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

if (avformat_alloc_output_context2(&outFmtCtx, NULL, NULL, outPath) < 0) return -3;

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;

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 (!(outFmtCtx->oformat->flags & AVFMT_NOFILE)) {
if (avio_open(&outFmtCtx->pb, outPath, AVIO_FLAG_WRITE) < 0) return -4;
}

if (avformat_write_header(outFmtCtx, NULL) < 0) return -5;

AVPacket pkt;
int videoDone = 0, audioDone = 0;

while (!videoDone || !audioDone) {
int videoRead = 0, audioRead = 0;

if (!videoDone && av_read_frame(videoFmtCtx, &pkt) >= 0) {
pkt.stream_index = outVideo->index;
av_packet_rescale_ts(&pkt, inVideo->time_base, outVideo->time_base);
if (av_interleaved_write_frame(outFmtCtx, &pkt) < 0) {
LOGE("Failed to write video packet");
}
av_packet_unref(&pkt);
videoRead = 1;
} else {
videoDone = 1;
}

if (!audioDone && av_read_frame(audioFmtCtx, &pkt) >= 0) {
pkt.stream_index = outAudio->index;
av_packet_rescale_ts(&pkt, inAudio->time_base, outAudio->time_base);
if (av_interleaved_write_frame(outFmtCtx, &pkt) < 0) {
LOGE("Failed to write audio packet");
}
av_packet_unref(&pkt);
audioRead = 1;
} else {
audioDone = 1;
}

// if both streams have no packets left, exit
if (!videoRead && !audioRead) break;
}

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);

LOGD("mergeAV finished successfully");
return 0;
Problem:
Die fusionierte Datei spielt Audio korrekt ab, aber das Video ist schwarz. Verwenden der Bibliotheken direkt. geladen < /p>
ordnungsgemäß geöffnete Eingangsformate und zugeteilte Ausgangskontext < /p>
Streams mit avcodec_parameters_copy < /p>
kopiert Ich verwende keine FFMPEG-Befehlszeile. Umschlüsse, Stream -Verschachtel usw.) wäre äußerst hilfreich.

Top