Search code examples
javayoutube-apimp3mp4javacv

Youtube doesn't accept the mp4 I generate with javacv from an mp3 and a jpeg


Youtube doesn't accept the mp4 I generatewith javacv from an mp3 and a jpeg

I am using the youtube java api to upload this and no exception is thrown while uploading. An error which I pasted below occurs when only when I go to the youtube site. Either to see the uploaded video or to upload the video by hand.
The mp4 file is 00:59 in length and 506 kb in size so I don't thing that should be an issue.

This is the code:

public static void MergeMp3Mp4JavaCv(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.setFrameRate(1);  
            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();  
         }  
    }

Youtube says:

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

Edit: the file plays flawlessly in windows media player
Edit 2:
I checked out https://support.google.com/youtube/answer/1722171?hl=en

Audio codec: AAC-LC
Channels: Stereo or Stereo + 5.1
Sample rate 96khz or 48khz

Video codec: H.264
Progressive scan (no interlacing)
High Profile
2 consecutive B frames
Closed GOP. GOP of half the frame rate.
CABAC
Variable bitrate. No bitrate limit required, though we offer recommended bit rates below for reference
Chroma subsampling: 4:2:0

I tried

recorder.setAudioCodec(avcodec.AV_CODEC_ID_H264 );
recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);

Tried a lot of other video codecs as well, but nothing works.
Does anyone know what I am doing wrong?


Solution

  • I eventually managed to get it working 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;
             }  
    
        }