Javacv: FFmpegFrameRecorder error -22 could not write header to null

Created on 30 Mar 2020  路  10Comments  路  Source: bytedeco/javacv

Hello everyone!
I'm trying to make Android app that opens the video using FFmpegFrameGrabber does some processing using opencv and then saves the result in new video using FFmpegFrameRecorder.

Whenever I'm trying to write video to file I get the following exception - avformat_write_header error() error -22: Could not write header to 'null'

I've been able to replicate the error on linux with this code:

InputStream is = new FileInputStream(args[0]);
            OutputStream os = new FileOutputStream("DEMO.mp4");

            frameGrabber = new FFmpegFrameGrabber(is);
            frameRecorder = new FFmpegFrameRecorder(os, frameGrabber.getAudioChannels());
            frameGrabber.setFormat("mp4");
            frameRecorder.setFormat("mp4");

            frameGrabber.start();
            frameRecorder.start();

            while (true){
                frame = frameGrabber.grabFrame();
                if(frame == null){
                    break;
                }
                frameRecorder.record(frame);
            }
            frameGrabber.stop();
            frameRecorder.stop();

            frameGrabber.close();
            frameRecorder.close();

            is.close();
            os.close();

which creates empty file and gives me this output in terminal


Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'java.io.BufferedInputStream@5cdd8682':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2019-11-17T10:17:15.000000Z
  Duration: 00:00:14.54, start: 0.000000, bitrate: 2414 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/bt709/smpte170m), 1080x1920 [SAR 1:1 DAR 9:16], 2321 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
    Metadata:
      creation_time   : 2019-11-17T12:46:20.000000Z
      handler_name    : ISO Media file produced by Google Inc. Created on: 11/17/2019.
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      creation_time   : 2019-11-17T12:46:20.000000Z
      handler_name    : ISO Media file produced by Google Inc. Created on: 11/17/2019.
[mp4 @ 0x7f5224bfaf80] No streams to mux were specified
org.bytedeco.javacv.FrameRecorder$Exception: avformat_write_header error() error -22: Could not write header to 'null'

thanks for help

question

Most helpful comment

Found the issue!!!
Basically the problem was initializing frame recorder before calling start method of frame grabber

All 10 comments

I don't think the mp4 format supports audio streams without video streams.
Try the aac format if that's what you're looking to do.

At this point I'm just basically trying to "copy" the video into new file. I've tried to change frame recorder initialization to this


            frameGrabber = new FFmpegFrameGrabber(is);
            frameRecorder = new FFmpegFrameRecorder("DEMO.mp4", frameGrabber.getImageWidth(), frameGrabber.getImageHeight());
            frameGrabber.setFormat("mp4");
            frameRecorder.setFormat("mp4");
            frameRecorder.setVideoCodec(frameGrabber.getVideoCodec());
            frameRecorder.setAudioCodec(avcodec.AV_CODEC_ID_H264);
            frameRecorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
            frameRecorder.setFrameRate(frameGrabber.getFrameRate());

And use sample mp4 video from sample-videos.com with exactly the same results as before

The end result of what I'm trying to achieve is on android let user select video file extract video frames, modify them using opencv and then save result as new video which can then be played using androids Videoview

In that case, you'll need to set both the image size and the number of channels, something like this:

frameRecorder = new FFmpegFrameRecorder("DEMO.mp4", frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());

I did, recorder still throws avformat_write_header error() error -22 : could not write header to 'null' exception when calling start method. This is my current code

InputStream is = new FileInputStream(args[0]);
frameGrabber = new FFmpegFrameGrabber(is);
frameRecorder = new FFmpegFrameRecorder("DEMO.mp4",
                            frameGrabber.getImageWidth(),
                            frameGrabber.getImageHeight(),
                            frameGrabber.getAudioChannels());
frameGrabber.setFormat("mp4");
frameRecorder.setFormat("mp4");
frameGrabber.start();
frameRecorder.start();

And the log?

this is the terminal output

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'java.io.BufferedInputStream@5cdd8682':
  Metadata:
    major_brand     : mp42
    minor_version   : 0
    compatible_brands: isommp42
    creation_time   : 2019-11-17T10:17:15.000000Z
  Duration: 00:00:14.54, start: 0.000000, bitrate: 2414 kb/s
    Stream #0:0(und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(tv, bt709/bt709/smpte170m), 1080x1920 [SAR 1:1 DAR 9:16], 2321 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
    Metadata:
      creation_time   : 2019-11-17T12:46:20.000000Z
      handler_name    : ISO Media file produced by Google Inc. Created on: 11/17/2019.
    Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
    Metadata:
      creation_time   : 2019-11-17T12:46:20.000000Z
      handler_name    : ISO Media file produced by Google Inc. Created on: 11/17/2019.
[mp4 @ 0x7f651cf25e40] No streams to mux were specified
org.bytedeco.javacv.FrameRecorder$Exception: avformat_write_header error() error -22: Could not write header to 'null'

That works just fine here... Maybe it's a problem with file permissions or something.

Found the issue!!!
Basically the problem was initializing frame recorder before calling start method of frame grabber

yes,you must start FFmpegFrameGrabber before initializing FFmpegFrameRecorder.
ex:

        FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(input);
        grabber.start();

        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(
                output,grabber.getImageWidth(), grabber.getImageHeight(), grabber.getAudioChannels());
        recorder.start();
Was this page helpful?
1 / 5 - 1 ratings

Related issues

Bahramudin picture Bahramudin  路  3Comments

UpAndDownAgain picture UpAndDownAgain  路  3Comments

nghiepvth picture nghiepvth  路  3Comments

fif10 picture fif10  路  3Comments

The-Crocop picture The-Crocop  路  5Comments