编程语言
首页 > 编程语言> > php – 使用curl下载视频的百分比

php – 使用curl下载视频的百分比

作者:互联网

我有一些托管在S3(.mp4和.mov)上的视频,其中一些相当大(1.2GB).
我想使用PHP包装器为FFmpeg从每个视频中获取第一帧,但我不想首先下载完整文件.

我真正想要做的是下载一定比例的文件,比如2%,这样我就可以保证我会得到第一帧.

我在这里找到了下载1mb文件的方法:https://code.i-harness.com/en/q/c09357

但是,这个代码的以下部分我真的不明白它是如何只下载1mb.

function myfunction($ch, $data)     {
    $length = fwrite($this->fh, $data);
    $size=&$this->size;

    if($length === FALSE) {
        return 0;
    } else {
        $size += $length;
    }

    // Downloads 1MB.

    return $size < 1024 * 1024 * 1 ? $length : 0;
}

对我说,将大小设置为文件的大小,然后如果大小小于1mb则返回长度,否则返回0.
现在,我知道它确实有效,因为我已经运行它,但我不知道它是如何工作的,所以我可以将其转换为获取文件的百分比.

下载1或2 MB的文件适用于较小的文件和mp4文件,但是.mov文件如果小于大约20mb则无法获得第一帧,并且一些帧在获取帧时会抛出除零错误,我猜从上面的函数返回0.

任何人都可以了解所有这些是如何工作的,或者甚至更好,如果你可以建议改进?

解决方法:

myfunction几乎肯定被设置为curl_exec的CURLOPT_WRITEFUNCTION回调函数,如果该函数返回0(或者除$data之外的任何数字),则curl将终止传输,curl_exec将返回CURLE_ABORTED_BY_CALLBACK错误代码.因此,在您下载> = 1 mebibyte后,curl_exec将因CURLE_ABORTED_BY_CALLBACK错误而停止.

我真正想要做的是下载一定比例的文件,比如2%,这样我就可以保证我会得到第一帧. – 根据电影编码,第一个mebibyte可能还不够.有一些编码方案(作为一个具体的例子,.mpeg电影可以这种方式编码),你需要从文件的末尾几个字节来渲染第一帧(iirc for .mpeg它叫做MOOV Atom – on mpeg MOOV原子位于文件末尾的电影,您需要从文件末尾开始几个字节来渲染第一帧.对于所有流优化的.mpeg电影,MOOV原子位于文件的开头,不是结束,你的第一个mebibyte计划会起作用,但是如果它最终你的计划将不起作用,除非整部电影是<1 mebibyte)
>更好的方法是让ffmpeg处理它. ffmpeg将知道要下载多少数据,并且将尝试仅下载所需的部分而不是整个电影,并且您需要像ffmpeg这样的程序来提取第一帧.

尝试

function getFirstFrameAsJpg(string $url):string{
        if(file_exists("/dev/null")){
            $ret=shell_exec("ffmpeg -i ".escapeshellarg($url)." -f image2pipe -frames 1 -r 1 -c:v:1 jpeg - 2>/dev/null");
        }else{
            // windows, probably, where /dev/null isn't supported but NUL works the same way.
            $ret=shell_exec("ffmpeg -i ".escapeshellarg($url)." -f image2pipe -frames 1 -r 1 -c:v:1 jpeg - 2>NUL");
        }
        return $ret;
}

它将在url中返回视频的第一帧作为.jpg图像的二进制. (意思是你可以做file_put_contents(‘image.jpg’,getFirstFrameAsJpg($url)); – 有趣的是,如果没有安装ffmpeg,$ret将为NULL,这意味着如果你使用strict_types = 1,你会得到一个异常,否则你会得到一个空字符串.)

ps允许潜在的黑客为此函数指定url之前,请确保验证它确实是一个http url,因为我没有考虑让黑客运行getFirstFrameAsJpg(“/ etc / passwd”)或类似的安全隐患.

如果您需要下载一堆标题,请考虑为ffmpeg设置一个代理方案,其中ffmpeg被告知从一个独特的proxy-url下载,并且仍然让ffmpeg处理要下载的电影的哪些部分,并确保为这样的代理实现http range header,因为如果从需要提取第一帧的电影的最后部分的电影中提取第一帧,ffmpeg将需要它.

(感谢c_14 @ freenode #ffmpeg for image2pipe命令)

标签:php,php-curl,php-ffmpeg
来源: https://codeday.me/bug/20190710/1425046.html