Reputation: 57421
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?
Upvotes: 4
Views: 4670
Reputation: 7646
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");
Upvotes: 9
Reputation: 1263
Your current approach just to download a random number of sequencial bytes would require you to do repair the partial file that you downloaded... a huge amount of work.
One alternative solution to your question above might be like that:
You would need to forward all Disk I/O read requests from your decoder to the S3 bucket. In case your decoder (avconv) supports reading from an inputstream, here is a good example how to override the read method:
How InputStream's read() method is implemented?
Another alternative is to use existing drivers that just let you access the S3 bucket as it was a local drive:
Windows: https://tntdrive.com/
Linux: https://tecadmin.net/mount-s3-bucket-centosrhel-ubuntu-using-s3fs/#
Upvotes: 3