Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating Thumbnail from video on S3 without downloading

There are some video files (mostly .mp4) stored in S3. They could be rather big. I need to get a thumbnail images for the video files - let's say 0.5 second's frame (to skip possible black screen etc.).

I can create the thumbnail if I download whole file but it's too long and I am trying to avoid this and download some minimal fragment.

I know how to download first N bytes from AWS S3 - request with specified range but the problem is the video file piece is corrupted and is not recognized as correct video.

I tried to emulate header bytes retrieving with the code

import java.io.FileInputStream;
import java.io.FileOutputStream;

public class Test {
    public static void main(String[] args) throws Exception {
        try(FileInputStream fis = new FileInputStream("D://temp//1.mp4");
            FileOutputStream fos = new FileOutputStream("D://temp//1_cut.mp4");
        ) {
            byte[] buf=new byte[1000000];
            fis.read(buf);
            fos.write(buf);
            fos.flush();
            System.out.println("Done");
        }
    }

}

To work with static file but the result 1_cut.mp4 is not valid. Neither player can recognize it nor avconv library.

Is there any way to download just fragment of video file and create an image from the fragment?

like image 736
StanislavL Avatar asked Dec 13 '22 19:12

StanislavL


1 Answers

Not sure if you need full java implementation but in case your file is accessible with direct or signed URL at S3 and you are ok to use ffmpeg than following should do the trick.

ffmpeg -i $amazon_s3_signed_url -ss 00:00:00.500 -vframes 1 thumbnail.png

You can use Amazon Java SDK to create a pre-signed URL and then execute the command above to create a thumbnail.

GeneratePresignedUrlRequest generatePresignedUrlRequest = 
                new GeneratePresignedUrlRequest(bucketName, objectKey);
generatePresignedUrlRequest.setMethod(HttpMethod.GET); 
generatePresignedUrlRequest.setExpiration(expiration);

URL url = s3client.generatePresignedUrl(generatePresignedUrlRequest); 
String urlString = url.toString();

Runtime run  = Runtime.getRuntime();
Process proc = run.exec("ffmpeg -i " + urlString +" -ss 00:00:00.500 -vframes 1 thumbnail.png");
like image 52
Babl Avatar answered Dec 16 '22 10:12

Babl