ikkhksvu 发表于 2024-11-1 15:11:49

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 &amp;&amp; <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);
    }




b1gc8v 发表于 2024-11-8 14:09:25

软文发布论坛开幕式圆满成功。 http://www.fok120.com
页: [1]
查看完整版本: php从远程URL获取(mp4 mp3)音视频的流媒介数据