bytedeco / javacv

Java interface to OpenCV, FFmpeg, and more
Other
7.55k stars 1.58k forks source link

[mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f15f8865780] moov atom not found #1369

Closed dajiangqingzhou closed 4 years ago

dajiangqingzhou commented 4 years ago

hello, guys I'm facing an issue when creating thumbnail of a mp4 video. The mp4 file is 178MB, no matter how big the variable 'defaultPart' is, it is always failed to create a thumbnail if 'defaultPart' is low than 178MB. The javacv version is : 1.4.4

Here is my code snippet(Using the same code , I can generate thumbnail for other mp4 videos which created by phone camera ):

    @Test
    public void testRecorderVideo() throws IOException {
        long defaultPart = 200 * 1024 * 1024;
        String filePath = "/home/user/video/no_thumbnail/20191008_164508.mp4";
        RandomAccessFile file = new RandomAccessFile(filePath, "r");
        long length = file.length();
        long times = length / defaultPart + 1;
        long startPosition = 0;
        int partSize = 0;
        boolean created = false;
        for (int i = 0; i < times; i++) {
            startPosition = i * defaultPart;
            partSize = (int) (startPosition + defaultPart > length ? length - startPosition : defaultPart);
            byte[] bytes = new byte[partSize];
            file.read(bytes);
            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
            try {
                createThumbnailFile(inputStream, "mp4");
                created = true;
            } catch (Exception e) {
                log.error("number [{}] part,error:[{}]", i, e.getMessage());
            }
        }
        if (created){
            log.info("success");
        }else {
            log.info("failed");
        }
    }

public static String createThumbnailFile(InputStream inputStream, String format) throws IOException {
        long start = System.currentTimeMillis();
        FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(inputStream);
        if (!Strings.isNullOrEmpty(format)) {
            frameGrabber.setFormat(format);
        }
        frameGrabber.start();
        String rotate = frameGrabber.getVideoMetadata("rotate");
        Frame frame = frameGrabber.grabImage();
        if (null != rotate && rotate.length() > 1) {
            OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
            IplImage iplImage = converter.convert(frame);
            frame = converter.convert(rotatePicture(iplImage, Integer.valueOf(rotate)));
        }
        String targetImgPath = path + System.currentTimeMillis() + ".png";
        doExecuteFrame(frame, targetImgPath);
        log.info("time: {}", System.currentTimeMillis() - start);
        return targetImgPath;
    }

the error message: [mov,mp4,m4a,3gp,3g2,mj2 @ 0x7f15f8865780] moov atom not found


But when I used the code as below, it works!! But in my case ,i have to use part of the video to create thumbnail, because my video is hurge, and it store in amazon s3, download

@Test
    public void ttttttt() throws IOException {
        String filePath = "/home/user/video/no_thumbnail/20191008_164508.mp4";
        VideoUtil.createThumbnail(filePath);
    }

public static String createThumbnailFile( String filePath) throws IOException {
        FileInputStream inputStream = new FileInputStream(filePath);
        long start = System.currentTimeMillis();
        FFmpegFrameGrabber frameGrabber = new FFmpegFrameGrabber(inputStream);
        frameGrabber.start();
        String rotate = frameGrabber.getVideoMetadata("rotate");
        Frame frame = frameGrabber.grabImage();
        if (null != rotate && rotate.length() > 1) {
            OpenCVFrameConverter.ToIplImage converter = new OpenCVFrameConverter.ToIplImage();
            IplImage iplImage = converter.convert(frame);
            frame = converter.convert(rotatePicture(iplImage, Integer.valueOf(rotate)));
        }
        String targetImgPath = path + System.currentTimeMillis() + ".png";
        doExecuteFrame(frame, targetImgPath);
        log.info("time: {}", System.currentTimeMillis() - start);
        return targetImgPath;
    }

Hoping for your help,thank you!!

saudet commented 4 years ago

The MP4 format usually requires seeking to the end of a file, which InputStream doesn't support without downloading the whole file.

dajiangqingzhou commented 4 years ago

The MP4 format usually requires seeking to the end of a file, which InputStream doesn't support without downloading the whole file.

@saudet thank you for your reply. Yeah , I guess so. I separate the mp4 file into several parts, and handle every part of them until thumbnail generated. In my opinions, the mp4 format message should be included by one of parts. But I still get failed. Why ?

saudet commented 4 years ago

No, unfortunately, as far as I know, that's not something FFmpeg supports for the "mp4" format...

dajiangqingzhou commented 4 years ago

No, unfortunately, as far as I know, that's not something FFmpeg supports for the "mp4" format... @saudet All right, thank you!

saudet commented 4 years ago

You should try to ask on the FFmpeg user mailing list though. There's most likely someone over there that can help you figure out something for that.

dajiangqingzhou commented 4 years ago

FFmpeg does not support reading the first part of video to grap frame. Fortunately there is another way to create thumbnail by prividing a http url to FFmpeg. FFmpeg can seek and read the video, rather then download the whole video.

saudet commented 4 years ago

Yes, FFmpeg supports seeking for most formats and protocols. The problem is InputStream that doesn't support seeking at all, so we can't expect that to work as well.

talhacomak commented 1 year ago

Did you find any solution to add thumbnail into the mp4 video file?