javacv
javacv copied to clipboard
Problem of FFmpegFrameRecorder when using javaCV to call ffmpeg for audio codec and output audio
Hello, I have a problem when using javaCV to call ffmpeg for audio transcoding. I don't know if it is a bug.
I built a FFmpegFrameGrabber
and set the output parameters for it.
- When I use stream output Using the following constructor
public FFmpegFrameRecorder(OutputStream outputStream, int audioChannels) {
this(outputStream.toString(), audioChannels);
this.outputStream = outputStream;
this.closeOutputStream = true;
}
, the final audio file will lack a ‘xing’ header data.
- When I use filename to specify his output audio path, Call the following constructor
public FFmpegFrameRecorder(String filename, int audioChannels) {
this(filename, 0, 0, audioChannels);
}
the generated audio file has no problem, including the "xing" header information. The two files differ by 180 bytes.
Hope to get answers and help from everyone, thanks!
The right side is the audio file I got when I used the stream for
FFmpegFrameRecorder
output. You can see that the right side lacks 'xing' header information than the left side. Other parts are consistent
Not all codecs and formats support streams well. Please report upstream.
I met the same problem. When I use the constructor with the OutputStream and running the program,it will report an error: org.bytedeco.javacv.FFmpegFrameRecorder$Exception: avformat_write_header error() error -22: Could not write header to ''. When I use the constructor with String,Program running fine. Have you solved the problem yet?
I met this same problem.Do you resolve this problem? this code does well.
frameGrabber.start();
recorder = new FFmpegFrameRecorder(out.getFile()), frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
this code does not work.
frameGrabber.start();
recorder = new FFmpegFrameRecorder(Files.newOutputStream(out.getFile().toPath()), frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
this is my full code
@Component
public class StandardTranscodingComponent extends AbstractTranscoding<InComponent, FileOutComponent> {
@Override
protected FileOutComponent doTrans(InComponent in, FileOutComponent out) {
final CodecComponent codec = out.codec();
//FFmpegLogCallback.set();
//avutil.av_log_set_level(AV_LOG_ERROR);
FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(in.getInputStream());
Frame captured_frame;
FFmpegFrameRecorder recorder = null;
try {
frameGrabber.start();
//this code does well
//recorder = new FFmpegFrameRecorder(out.getFile(), frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
//this code does not work
recorder = new FFmpegFrameRecorder(Files.newOutputStream(out.getFile().toPath()), frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
//video
recorder.setVideoCodec(codec.getVideoCodec() == null ? frameGrabber.getVideoCodec() : codec.getVideoCodec());
recorder.setFormat(codec.getVideoFormat());
recorder.setFrameRate(codec.getVideoFrameRate() == null ? frameGrabber.getFrameRate() : codec.getVideoFrameRate());
recorder.setVideoBitrate(codec.getVideoBitrate() == null ? frameGrabber.getVideoBitrate() : codec.getVideoBitrate());
recorder.setVideoOptions(frameGrabber.getVideoOptions());
//audio
recorder.setAudioBitrate(codec.getAudioBitrate() == null ? frameGrabber.getAudioBitrate() : codec.getAudioBitrate());
recorder.setAudioOptions(codec.getAudioOptions() == null ? frameGrabber.getAudioOptions() : codec.getAudioOptions());
recorder.setAudioQuality(codec.getAudioQuality() == null ? 0 : codec.getAudioQuality());
recorder.setSampleRate(codec.getAudioSampleRate() == null ? frameGrabber.getSampleRate() : codec.getAudioSampleRate());
recorder.setAudioCodec(codec.getAudioCodec() == null ? frameGrabber.getAudioCodec() : codec.getAudioCodec());
recorder.start();
while (true) {
try {
captured_frame = frameGrabber.grabFrame();
if (captured_frame == null) {
break;
}
recorder.record(captured_frame);
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (recorder != null)
recorder.stop();
} catch (Exception ignored) {
}
try {
if (recorder != null)
recorder.release();
} catch (Exception ignored) {
}
try {
frameGrabber.stop();
} catch (Exception ignored) {
}
try {
frameGrabber.release();
} catch (Exception ignored) {
}
try {
if (recorder != null)
recorder.close();
} catch (Exception ignored) {
}
try {
frameGrabber.close();
} catch (Exception ignored) {
}
}
return out;
}
}
this is the logs
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'java.io.BufferedInputStream@7dd20faf':
Metadata:
major_brand : qt
minor_version : 0
compatible_brands: qt
creation_time : 2023-04-06T06:53:54.000000Z
com.apple.quicktime.location.accuracy.horizontal: 35.000000
com.apple.quicktime.location.ISO6709: +30.5429+104.0525+471.564/
com.apple.quicktime.make: Apple
com.apple.quicktime.model: iPhone 12 Pro
com.apple.quicktime.software: 16.3.1
com.apple.quicktime.creationdate: 2023-04-06T14:53:53+0800
Duration: 00:00:11.11, start: 0.000000, bitrate: 10695 kb/s
Stream #0:0[0x1](und): Video: hevc (Main) (hvc1 / 0x31637668), yuvj420p(pc, smpte170m/smpte432/bt709), 1920x1440, 9921 kb/s, 29.96 fps, 29.97 tbr, 600 tbn (default)
Metadata:
creation_time : 2023-04-06T06:53:54.000000Z
handler_name : Core Media Video
vendor_id : [0][0][0][0]
encoder : HEVC
Side data:
displaymatrix: rotation of -90.00 degrees
Stream #0:1[0x2](und): Audio: pcm_s16le (lpcm / 0x6D63706C), 44100 Hz, 1 channels, s16, 705 kb/s (default)
Metadata:
creation_time : 2023-04-06T06:53:54.000000Z
handler_name : Core Media Audio
vendor_id : [0][0][0][0]
Stream #0:2[0x3](und): Data: none (mebx / 0x7862656D), 0 kb/s (default)
Metadata:
creation_time : 2023-04-06T06:53:54.000000Z
handler_name : Core Media Metadata
Stream #0:3[0x4](und): Data: none (mebx / 0x7862656D), 52 kb/s (default)
Metadata:
creation_time : 2023-04-06T06:53:54.000000Z
handler_name : Core Media Metadata
[libopenh264 @ 0000025a84448500] Slice count will be set automatically
[libopenh264 @ 0000025a84448500] [OpenH264] this = 0x0000025aef39ed20, Warning:layerId(0) doesn't support profile(578), change to UNSPECIFIC profile
[libopenh264 @ 0000025a84448500] [OpenH264] this = 0x0000025aef39ed20, Warning:bEnableFrameSkip = 0,bitrate can't be controlled for RC_QUALITY_MODE,RC_BITRATE_MODE and RC_TIMESTAMP_MODE without enabling skip frame.
[mp4 @ 0000025a84b90c80] muxer does not support non seekable output
[aac @ 0000025a84448900] Qavg: nan
the format of InputStream is MOV the format of OutStream is H264,Mp4