Javacv: Generate a video that youtube will accept

Created on 14 Apr 2018  路  7Comments  路  Source: bytedeco/javacv

I am trying to upload a video created with javac to Youtube.
I checked out https://support.google.com/youtube/answer/1722171?hl=en to see which settings to use.
I tried the codec youtube recommends and a whole lot of others hoping that one will work.
The video is an mp4 made by joining an mp3 with a jpeg.
This is the code I use.

public static void MergeMp3AndJpegIntoMp4(String path2ImageFile,String path2AudioFile, String path2OutputFile) throws IOException
{

    IplImage ipl = cvLoadImage(path2ImageFile);
    int height = ipl.height();
    int width = ipl.width();
    if(height%2!=0) height = height+1;
    if(width%2!=0) width = width+1;

    OpenCVFrameConverter.ToIplImage grabberConverter = new OpenCVFrameConverter.ToIplImage();  
    FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(path2OutputFile,width,height); 
    FrameGrabber audioFileGrabber = new FFmpegFrameGrabber(path2AudioFile);
    try 
    {  
        audioFileGrabber.start();
        //recorder.setAudioCodec(avcodec.AV_CODEC_ID_MPEG4 );
        //recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        //recorder.setVideoCodec(avcodec.AV_CODEC_ID_MJPEG);
        //codec not found: recorder.setVideoCodec(avcodec.AV_CODEC_ID_MJPEGB); 
        //codec not found: recorder.setVideoCodec(avcodec.AV_CODEC_ID_MPEG1VIDEO); 
        //could not open video codec: recorder.setVideoCodec(avcodec.AV_CODEC_ID_LJPEG);
        //recorder.setVideoCodec(avcodec.AV_CODEC_ID_RAWVIDEO);
        //video codec not found recorder.setVideoCodec(avcodec.AV_CODEC_ID_MSMPEG4V1); 
        recorder.setAudioCodec(avcodec.AV_CODEC_ID_H264 );

        recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
        //could not encode audio packet recorder.setAudioCodec(avcodec.AV_CODEC_ID_AC3);
        //audio codec not found: recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC_LATM);

        recorder.setFrameRate(24);  
        //recorder.setFrameRate(audioFileGrabber.getFrameRate());
        recorder.setVideoBitrate(audioFileGrabber.getAudioBitrate());  
        recorder.setFormat("mp4");  
        recorder.setAudioChannels(1);
        recorder.start();  

        recorder.record(grabberConverter.convert(ipl));  
        Frame frame = null;
        while ((frame = audioFileGrabber.grabFrame())!=null) 
        {
            recorder.record(frame);
        }

        recorder.stop();  
        audioFileGrabber.stop();
     }  
     catch (org.bytedeco.javacv.FrameRecorder.Exception e){  
       e.printStackTrace();  
     }  
}

The file generates succesfully, but youtube will never accept it, no matter what I try.
This is what Youtube says:

The video has failed to process. Please make sure you are uploading a supported file type.

Does anyone know what I am doing wrong?

question

All 7 comments

Check the supported formats and try to create a file like that.

mp4 is a supported format. In fact it is the preferred format as can be seen in the link I posted above.

I managed to make it work like this;

public static void MergeMp3AndJpegIntoMp4(String path2ImageFile,String path2AudioFile, String path2OutputFile) throws IOException
    {

        IplImage ipl = cvLoadImage(path2ImageFile);
        int height = ipl.height();
        int width = ipl.width();
        if(height%2!=0) height = height+1;
        if(width%2!=0) width = width+1;

        OpenCVFrameConverter.ToIplImage grabberConverter = new OpenCVFrameConverter.ToIplImage();  
        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(path2OutputFile,width,height); 
        FrameGrabber audioFileGrabber = new FFmpegFrameGrabber(path2AudioFile);
        try 
        {  
            audioFileGrabber.start();

            recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264 );//AV_CODEC_ID_VORBIS
            recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);//AV_CODEC_ID_MP3 //AV_CODEC_ID_AAC

            recorder.setFormat("mp4");  
            recorder.setAudioChannels(2);
            recorder.start();  

            Frame frame = null;
            while ((frame = audioFileGrabber.grabFrame())!=null) 
            {   recorder.record(grabberConverter.convert(ipl));  
                recorder.record(frame);
            }

            recorder.stop();  
            audioFileGrabber.stop();
         }  
         catch (org.bytedeco.javacv.FrameRecorder.Exception e){  
           e.printStackTrace();  
           throw e;
         }  

    }

Great! Thanks for the feedback.

BTW, if you could wrap this up in a file and send a pull request to add it to the samples directory that would be awesome!

@saudet Sure, I'm wasn't sure if this was the best way of doing it(it does work but I'm under the impression that the size of the generated file is a bit larger than it could be - I really don't know much about this technology, just needed it for something), but if you think it is I will do just that as soon as I get the time.

Yes, it doesn't need to be perfect. Somebody else can optimize it later. :)
Thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

iamazy picture iamazy  路  4Comments

UpAndDownAgain picture UpAndDownAgain  路  3Comments

y4nnick picture y4nnick  路  3Comments

jakubondrus picture jakubondrus  路  4Comments

ahmedaomda picture ahmedaomda  路  4Comments