从 S3 上的视频创建缩略图而无需下载

Creating Thumbnail from video on S3 without downloading

S3 中存储了一些视频文件(主要是 .mp4)。它们可能相当大。我需要获取视频文件的缩略图 - 比如说 0.5 秒的帧(以跳过可能的黑屏等)。

如果我下载整个文件,我可以创建缩略图,但它太长了,我试图避免这种情况并下载一些最小的片段。

我知道 how to download first N bytes from AWS S3 - 要求指定范围,但问题是视频文件已损坏,无法识别为正确的视频。

我尝试用代码

模拟头字节检索
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");
        }
    }

}

要使用静态文件,但结果 1_cut.mp4 无效。玩家无法识别它,也无法识别 avconv 图书馆。

有没有办法只下载视频文件的片段并从该片段创建图像?

不确定您是否需要完整的 java 实施,但如果您的文件可以在 S3 上直接访问或签名 URL 并且您可以使用 ffmpeg 而不是下面应该做的诀窍。

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

您可以使用Amazon Java SDK创建预签名URL然后执行上面的命令创建缩略图。

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");

您当前的方法只是下载随机数量的连续字节,这将需要您修复下载的部分文件...需要大量工作。

上述问题的另一种解决方案可能是这样的:

您需要将所有磁盘 I/O 读取请求从您的解码器转发到 S3 存储桶。如果您的解码器 (avconv) 支持从输入流读取,这里有一个很好的示例如何覆盖读取方法:

另一种选择是使用现有的驱动程序,让您像访问本地驱动器一样访问 S3 存储桶:

Windows: https://tntdrive.com/

Linux: https://tecadmin.net/mount-s3-bucket-centosrhel-ubuntu-using-s3fs/#