当前位置: 首页 > 工具软件 > jQuery rpc > 使用案例 >

aria2 jsonrpc使用体验(php & jquery)&下载m3u8里ts文件升级版

舒博雅
2023-12-01

前段时间用php写了1个通过aria2下载m3u8里面ts文件到本地的功能,因为没有实时显示进度,而且还需要打开PHP的shell_exec,可能会对系统安全存在风险,所以想有没有其他替代方法。

刚好这几天用到aria2配套的AriaNg,他是通过aria2的jsonrpc来实现的,所以想是不是也可以使用jsonrpc来下载。

以下是jsonrpc传值得标准基础格式,记录备忘。

//下面这个是单个文件下载的
{
	"jsonrpc": "2.0", 
	"id": "这个可以自定义",
	"method": "aria2.addUri",
	"params":[
		"token:这里写你aria2.conf里设置的rpc-secret",
		["http://xxx.com/xxx.xx  这里写需要下载的文件地址"],
		{"dir":"这里写需要下载的绝对路径,这一行可以不填,则默认下载到aria2.conf里设置的下载地址"}
	]
}


//下面这个是多个文件下载的,就是把上面这个作为数组的元素就行了
[
{
	"jsonrpc": "2.0", 
	"id": "这个可以自定义",
	"method": "aria2.addUri",
	"params":[
		"token:这里写你aria2.conf里设置的rpc-secret",
		["http://xxx.com/xxx.xx  这里写需要下载的文件地址"],
		{"dir":"这里写需要下载的绝对路径,这一行可以不填,则默认下载到aria2.conf里设置的下载地址"}
	]
},
{
	"jsonrpc": "2.0", 
	"id": "这个可以自定义",
	"method": "aria2.addUri",
	"params":[
		"token:这里写你aria2.conf里设置的rpc-secret",
		["http://xxx.com/xxx.xx  这里写需要下载的文件地址"],
		{"dir":"这里写需要下载的绝对路径,这一行可以不填,则默认下载到aria2.conf里设置的下载地址"}
	]
}
]

然后就是把这个作为json数据传给aria2的jsonrpc就行了,下面用php和jquery来举例

先是PHP,通过curl来实现

<?php
    $url = "http://127.0.0.1:6800/jsonrpc";
    $data = '
        {
	"jsonrpc": "2.0", 
	"id": "这个可以自定义",
	"method": "aria2.addUri",
	"params":[
		"token:这里写你aria2.conf里设置的rpc-secret",
		["http://xxx.com/xxx.xx  这里写需要下载的文件地址"],
		{"dir":"这里写需要下载的绝对路径,这一行可以不填,则默认下载到aria2.conf里设置的下载地址"}
	]
        }
        ';
    
    echo postCurl($url,$data);
    
    function postCurl($url,$data)
    {
      /**
      if($type == 'json'){
          $data = json_encode($data);//对数组进行json编码
          $header= array("content-type: application/x-www-form-urlencoded; charset=UTF-8");
      }
      **/
      $curl = curl_init();
      curl_setopt($curl,CURLOPT_URL,$url);
      curl_setopt($curl,CURLOPT_POST,1);
      curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,false);
      curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,false);
      if(!empty($data)){
          curl_setopt($curl,CURLOPT_POSTFIELDS,$data);
      }
      curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);
      //curl_setopt($curl,CURLOPT_HTTPHEADER,$header);
      $res = curl_exec($curl);
      if(curl_errno($curl)){
          echo 'Error+'.curl_error($curl);
      }
      curl_close($curl);
      return $res;
    }
?>

然后来jquery的,需要下载jquery

<script src="jquery-3.6.0.min.js"></script> <!--需要jquery支持-->
<script type="text/javascript">
	var data = {
				"jsonrpc": "2.0", 
				"id": "这个可以自定义",
				"method": "aria2.addUri",
				"params":[
						"token:这里写你aria2.conf里设置的rpc-secret",
						["http://xxx.com/xxx.xx  这里写需要下载的文件地址"],
						{"dir":"这里写需要下载的绝对路径,这一行可以不填,则默认下载到aria2.conf里设置的下载地址"}
					]
				};
        
    download_file(JSON.stringify(data));  //这里不能直接传json,需要转换成字符串
    
    //执行下载
	function download_file(data){
		//console.log(data)
		$.ajax({
			url: "http://127.0.0.1:6800/jsonrpc",
			data: data,
			type: "post",
			//async: false,//false为同步
			dataType: "json",
			success: function(obj) {
				console.log(obj)
				//这里放了ariang,添加jsonrpc之后,可以通过ariang查看下载进度,当然直接用ariang下载也方便,只是只能添加文件真实地址
				location.href="ariang/index.html";
			},
			error:function (e) {
          //返回500错误 或者其他 http状态码错误时 需要在error 回调函数中处理了 并且返回的数据还不能直接alert,需要使用
          //$.parseJSON 进行转译    res.msg 是自己组装的错误信息通用变量  
				var res = $.parseJSON(e.responseText);
				console.log(res);
			}
		});
	}
</script>

最后来结合起来,下载m3u8里面的ts文件到本地(因为ariang应该不支持分析m3u8文件里的ts列表,所以自己写了个php来分析获取)

这个最后可以通过http://xxx.com/xxx.php?name=xxx&m3u8=http://xxx.com/index.m3u8来传参执行

<?php
    //aria2的jsonrpc地址
    $aria_jsonrpc = "http://localhost:6800/jsonrpc";
    
    if(isset($_GET['m3u8'])){
        //获取url
        $url = $_GET['m3u8'];
        //获取网址域名
        $urlarr = explode('/',$url);
        $domain = $urlarr[0].'//'.$urlarr[2].'/';
        $domain_dir = $urlarr[3].'/';
        
        //先判断传入的m3u8里面有没有直接包含ts地址,还是套着一个m3u8文件
        $url = Check_m3u8($url);
        
        
        //定义m3u8名字,用于区分不同的m3u8,用自定义则获取,没有则通过网址里的信息来
        $m3u8_name = $_GET['name']!=null && $_GET['name']!='' ? $_GET['name'] : $urlarr[3]."_".$urlarr[4];
        //判断、新建tslist文件夹,用于存储
        if(!file_exists('tslist/')){
          mkdir('tslist/',0777); 
        }
        //通过名称建立不同文件夹
        $dir = 'tslist/'.$m3u8_name.'/';
        $ts_dir = $dir.'ts/';
        if(!file_exists($dir)){
          mkdir($dir,0777); 
        }
        if(!file_exists($ts_dir)){
          mkdir($ts_dir,0777); 
        }
        
        //获取m3u8文件里面的信息,并生成数组
        $content = explode(chr(10),file_get_contents($url));
        $i = 1;
        //这个是用来单独存储ts文件真实网址的
        $ts_url ='';
        //这个是用来新建本地m3u8文件,保证路径与下载保存的ts文件路径一致
        $m3u8_content = '';
        $ts_url_json = '';
        //通过循环来获取m3u8文件里每一行的信息
        foreach ($content as $v){
            //获取Key,并保存到本地,这个如果想完全本地播放m3u8的话是必须的
            if(strstr($v,'.key')){
                $get_key = explode('"',$v);
                $key_url = $get_key[1];
                //如不带域名,则添加,带了就保留
                $key_urls = strstr($key_url,'http') ? $key_url : $domain.$key_url;
                file_put_contents($dir.$m3u8_name.'_key.key',file_get_contents($key_urls));
                //用于本地m3u8文件,key路径与m3u8文件在同一个文件夹
                $m3u8_content .= $get_key[0].'"'.$m3u8_name.'_key.key"'.chr(10);
            }
            //获取正式ts文件网址
            elseif(strstr($v,'.ts')){
                //如不带域名,则添加,带了就保留  $domain_dir
                $ts_urls = strstr($v,'http') ? $v : (strstr($v,'/') ? $domain.$v : $domain.$domain_dir.$v );
                $ts_url .= $ts_urls.chr(10);
                //获取ts文件名
                $ts_name = explode('/',$v);
                $m3u8_content .= 'ts/'.end($ts_name).chr(10);
                $ts_url_json .= Add_to_Json($i,$ts_urls,$ts_dir);
                $i++;
            }
            else{
                $m3u8_content .= $v.chr(10);
            }
            
        }
        file_put_contents($dir.$m3u8_name.'.m3u8',rtrim($m3u8_content,chr(10)));
        //这个生成json文件,可忽略
        file_put_contents($dir.$m3u8_name.'.json','['.rtrim($ts_url_json,',').']');
        
        //赋值最终用于传给jsonrpc的json值
        $ts_json = ('['.rtrim($ts_url_json,',').']');
        echo 'http://'.$_SERVER['HTTP_HOST'].'/'.$dir.$m3u8_name.'.m3u8',"<br>";
        
        //执行curl,这里放echo只为看是否成功
        echo postCurl($aria_jsonrpc,$ts_json);
        //如果你有ariang的话,就上面不echo,改为直接打开ariang页面查看
        //echo '<script type="text/javascript">location.href="ariang/index.html";</script>';
    }else{
        echo "请传入m3u8地址,以?name=xxx&m3u8=http://xxxx.com/xxx.m3u8的方式";
    }
    
    //把ts地址拼接进aria2的jsonrpc支持的格式
    function Add_to_Json($id,$tsurl,$ts_dir){
        $json_str = '
        {
            "jsonrpc": "2.0", 
            "id": '.$id.',
            "method": "aria2.addUri",
            "params":[
                "token:thisisaria2forsham",
                ["'.$tsurl.'"],
                {"dir":"'.dirname(__FILE__).'/'.$ts_dir.'"}
            ]
        },';
			return $json_str;
    };
    
    //curl_post
    function postCurl($url,$data)
    {
      /**
      if($type == 'json'){
          $data = json_encode($data);//对数组进行json编码
          $header= array("content-type: application/x-www-form-urlencoded; charset=UTF-8");
      }
      **/
      $curl = curl_init();
      curl_setopt($curl,CURLOPT_URL,$url);
      curl_setopt($curl,CURLOPT_POST,1);
      curl_setopt($curl,CURLOPT_SSL_VERIFYPEER,false);
      curl_setopt($curl,CURLOPT_SSL_VERIFYHOST,false);
      if(!empty($data)){
          curl_setopt($curl,CURLOPT_POSTFIELDS,$data);
      }
      curl_setopt($curl,CURLOPT_RETURNTRANSFER,1);
      //curl_setopt($curl,CURLOPT_HTTPHEADER,$header);
      $res = curl_exec($curl);
      if(curl_errno($curl)){
          echo 'Error+'.curl_error($curl);
      }
      curl_close($curl);
      return $res;
    }
    
    //判断m3u8里面有没有再包含m3u8文件
    function Check_m3u8($url){
        global $domain;
        $m3u8_content = file_get_contents($url);
        if(strstr($m3u8_content,'.m3u8')){
            $m3u8_contents = explode(chr(10),$m3u8_content);
            foreach($m3u8_contents as $m3u8){
                if(strstr($m3u8,'.m3u8')){
                    $url = strstr($m3u8,'http') ? $m3u8 : $domain.$m3u8;
                    break;
                }
            }
            Check_m3u8($url);
        }
        return $url;
    }
?>

 类似资料: