php从远程URL获取(mp4 mp3)音视频的流媒介数据
<span style="color: black;">/*** 从远程URL中获取<span style="color: black;">媒介</span>(如 mp4 mp3)的内容
* <span style="color: black;">@param</span> mixed $file_url
* <span style="color: black;">@param</span> mixed $media_type
* <span style="color: black;">@param</span> mixed $curl_time_out
* <span style="color: black;">@throws</span> Exception
* <span style="color: black;">@return</span> mixed
*/</span>
<span style="color: black;">public</span> <span style="color: black;">static</span> <span style="color: black;"><span style="color: black;">function</span> <span style="color: black;">getRemoteMediaContent</span><span style="color: black;">($file_url = , $media_type = <span style="color: black;">"Content-Type: video/mp4"</span>, $curl_time_out =<span style="color: black;">600000</span>)</span>
</span>{
<span style="color: black;">if</span> (<span style="color: black;">empty</span>($file_url)) {
<span style="color: black;">throw</span> <span style="color: black;">new</span> <span style="color: black;">Exception</span>(<span style="color: black;">请传入远程url<span style="color: black;">位置</span></span>, Response::PARAM_ERROR);
}
$parse_bool = parse_url($file_url);
<span style="color: black;">if</span>($parse_bool ===<span style="color: black;">false</span>) {
<span style="color: black;">throw</span> <span style="color: black;">new</span> <span style="color: black;">Exception</span>(<span style="color: black;">请传入有效的远程url<span style="color: black;">位置</span></span>, Response::PARAM_ERROR);
}
ini_set(<span style="color: black;">max_execution_time</span>, <span style="color: black;">0</span>);
$useragent = <span style="color: black;">"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.96 Safari/537.36"</span>;
<span style="color: black;">//开一个ch 用来获取资源HTTP头信息(<span style="color: black;">重点</span>获取视频长度)</span>
$ch = curl_init();
<span style="color: black;">// TRUE 会输出所有的信息,写入到STDERR,或在CURLOPT_STDERR中指定的文件。</span>
curl_setopt($ch, CURLOPT_VERBOSE, <span style="color: black;">1</span>);
<span style="color: black;">//<span style="color: black;">准许</span> cURL 函数执行的最长秒数</span>curl_setopt($ch, CURLOPT_TIMEOUT, $curl_time_out);<span style="color: black;">//需要获取的 URL <span style="color: black;">位置</span>,<span style="color: black;">亦</span><span style="color: black;">能够</span>在curl_init() 初始化会话的时候</span>
curl_setopt($ch, CURLOPT_URL, $file_url);
<span style="color: black;">//TRUE 时将会<span style="color: black;">按照</span>服务器返回 HTTP 头中的 "Location: " 重定向。</span>
<span style="color: black;">//(<span style="color: black;">重视</span>:这是递归的,"Location: " 发送几次就重定向几次,除非设置了 CURLOPT_MAXREDIRS,限制最大重定向次数。)。</span>
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, <span style="color: black;">true</span>);
<span style="color: black;">// 启用时会将头文件的信息<span style="color: black;">做为</span>数据流输出(<span style="color: black;">重视</span><span style="color: black;">这儿</span><span style="color: black;">第1</span>步只需要获取资源HTTP头信息 <span style="color: black;">重点</span>是为了得到内容的长度)</span>
curl_setopt($ch, CURLOPT_HEADER, <span style="color: black;">true</span>);
<span style="color: black;">// TRUE 强制获取一个新的连接,而不是缓存中的连接</span>
curl_setopt($ch, CURLOPT_FRESH_CONNECT, <span style="color: black;">true</span>);
<span style="color: black;">// FALSE 禁止 cURL 验证对等证书(peerscertificate)。要验证的交换证书<span style="color: black;">能够</span>在 CURLOPT_CAINFO 选项中设置,或在 CURLOPT_CAPATH中设置证书目录</span>
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, <span style="color: black;">0</span>);
<span style="color: black;">//向服务器发送,<span style="color: black;">包括</span>了<span style="color: black;">拜访</span>者系统引擎版本、浏览器信息的字段信息。</span>
<span style="color: black;">//<span style="color: black;">通常</span>服务器识别出是爬虫请求,会拒绝<span style="color: black;">拜访</span>。<span style="color: black;">因此</span>此时设置User-Agent,<span style="color: black;">能够</span>将爬虫伪装成用户<span style="color: black;">经过</span>浏览器<span style="color: black;">拜访</span>。</span>
curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
<span style="color: black;">// TRUE 时将不输出 BODY 部分。<span style="color: black;">同期</span> Mehtod 变<span style="color: black;">成为了</span> HEAD。修改为 FALSE 时不会变成 GET</span>
curl_setopt($ch, CURLOPT_NOBODY, <span style="color: black;">true</span>);
<span style="color: black;">//TRUE 将curl_exec()获取的信息以字符串返回,而不是直接输出</span>
<span style="color: black;">//<span style="color: black;">这儿</span><span style="color: black;">咱们</span>不需要关心</span>
curl_setopt($ch, CURLOPT_RETURNTRANSFER, <span style="color: black;">true</span>);
<span style="color: black;">//执行 cURL 会话 <span style="color: black;">这儿</span><span style="color: black;">咱们</span>只关心头信息 <span style="color: black;">因此</span>不需要获取返回的内容</span>
curl_exec($ch);
<span style="color: black;">//获取一个cURL连接资源句柄的信息 <span style="color: black;">这儿</span><span style="color: black;">重点</span>用来读取长度</span>
<span style="color: black;">//-- CURLINFO_CONTENT_LENGTH_DOWNLOAD 从Content-Length: field中读取的下载内容长度</span>$filesize = $length = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD);<span style="color: black;">//发送请求的<span style="color: black;">媒介</span>头类型</span>
header($media_type);
<span style="color: black;">//------ 获取资源长度告一段落 以下用于获取<span style="color: black;">媒介</span>视频的二进制内容------</span>
<span style="color: black;">//总共接收的数据<span style="color: black;">体积</span></span>header(<span style="color: black;">"Content-length: "</span> . $filesize);
<span style="color: black;">//接收的数据类型是 字节类型 即二进制</span>
header(<span style="color: black;">Accept-Ranges: bytes</span>);
$partialContent = <span style="color: black;">false</span>;
$offset = <span style="color: black;">0</span>; <span style="color: black;">//读取数据的初始位置</span>
<span style="color: black;">if</span> (<span style="color: black;">isset</span>($_SERVER[<span style="color: black;">HTTP_RANGE</span>])) {
$partialContent = <span style="color: black;">true</span>;
<span style="color: black;">//<span style="color: black;">得到</span>初始位置和数据长度</span>
preg_match(<span style="color: black;">/bytes=(\d+)-(\d+)?/</span>, $_SERVER[<span style="color: black;">HTTP_RANGE</span>], $matches);
$offset = intval($matches[<span style="color: black;">1</span>]);
$length = $filesize - $offset - <span style="color: black;">1</span>;
<span style="color: black;">/***
断点续传: <span style="color: black;">便是</span>从文件上次中断的<span style="color: black;">地区</span><span style="color: black;">起始</span>重新下载或上传,当下载或上传文件的时候,<span style="color: black;">倘若</span><span style="color: black;">无</span>实现断点续传功能,<span style="color: black;">那样</span>每次<span style="color: black;">显现</span><span style="color: black;">反常</span><span style="color: black;">或</span>用户主动的暂停,都会去重头下载,
<span style="color: black;">这般</span>很浪费时间。<span style="color: black;">因此</span>断点续传的功能就应运而生了。要实现断点续传的功能,需要客户端记录下当前的下载或上传进度,
并在需要续传的时候<span style="color: black;">通告</span>服务端<span style="color: black;">这次</span>需要下载或上传的内容片段。
HTTP的请求上定义了断点续传<span style="color: black;">关联</span>的HTTP头Range字段和Content-Range字段。
<span style="color: black;">例如</span>说客户端在Header中设置Range=bytes22223333- <span style="color: black;">暗示</span>文件从22223333字节<span style="color: black;">起始</span>传,前面的字节<span style="color: black;">不消</span>传了。
服务器收到请求,返回206 Partial Content。 Content-Length=44445555,Content-Range=bytes22223333-44445554/44445555
*/</span>
<span style="color: black;">//Chrome在<span style="color: black;">针对</span>MP3文件的<span style="color: black;">拜访</span>,返回的都是206 Partial Content</span>
header(<span style="color: black;">HTTP/1.1 206 Partial Content</span>);
<span style="color: black;">//每次接收数据的的范围</span>
header(<span style="color: black;">Content-Range: bytes</span> . $offset . <span style="color: black;">-</span> . ($offset + $length) . <span style="color: black;">/</span> . $filesize);
}
<span style="color: black;">//重新开一个ch 用来获取内容</span>
$ch = curl_init();
<span style="color: black;">//<span style="color: black;">倘若</span>支持分段发送数据</span>
<span style="color: black;">if</span> ($partialContent && <span style="color: black;">isset</span>($_SERVER[<span style="color: black;">HTTP_RANGE</span>])) {
<span style="color: black;">//获取上次的范围</span>
preg_match(<span style="color: black;">/bytes=(\d+)-(\d+)?/</span>, $_SERVER[<span style="color: black;">HTTP_RANGE</span>], $matches);
$offset = intval($matches[<span style="color: black;">1</span>]); <span style="color: black;">//<span style="color: black;">起始</span>位置</span>$length = $filesize - $offset -<span style="color: black;">1</span>; <span style="color: black;">//获取长度</span>
<span style="color: black;">//发送带有Range的请求头</span>
$headers = [<span style="color: black;">Range: bytes=</span> . $offset . <span style="color: black;">-</span>. ($offset + $length) . ];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
curl_setopt($ch, CURLOPT_VERBOSE,<span style="color: black;">1</span>);
curl_setopt($ch, CURLOPT_TIMEOUT, $curl_time_out);
curl_setopt($ch, CURLOPT_URL, $file_url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION,<span style="color: black;">true</span>);
<span style="color: black;">// 启用时会将头文件的信息<span style="color: black;">做为</span>数据流输出(<span style="color: black;">这儿</span>只需要获取内容 <span style="color: black;">因此</span>设置为false)</span>
curl_setopt($ch, CURLOPT_HEADER, <span style="color: black;">false</span>);
curl_setopt($ch, CURLOPT_FRESH_CONNECT,<span style="color: black;">true</span>);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, <span style="color: black;">0</span>);
curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
<span style="color: black;">// TRUE 时将不输出 BODY 部分。<span style="color: black;">同期</span> Mehtod 变<span style="color: black;">成为了</span> HEAD。修改为 FALSE 时不会变成 GET [ <span style="color: black;">这儿</span><span style="color: black;">咱们</span>不需要输出头信息]</span>
curl_setopt($ch, CURLOPT_NOBODY, <span style="color: black;">false</span>);
<span style="color: black;">// TRUE 将curl_exec()获取的信息以字符串返回,而不是直接输出</span>
<span style="color: black;">//<span style="color: black;">这儿</span>我们需要直接输出二进制数据</span>
curl_setopt($ch, CURLOPT_RETURNTRANSFER, <span style="color: black;">false</span>);
<span style="color: black;">//执行 cURL 会话</span>
curl_exec($ch);
}
软文发布论坛开幕式圆满成功。 http://www.fok120.com
页:
[1]