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

aria2+RPC+m3u8下载工具(windows版)

萧光华
2023-12-01

今天在电脑上把上次弄的aria2下载工具丰富了下,其实比较简单,但是Sham太菜,所以折腾了蛮久,备忘&分享下:

首先就是下载和配置必须的软件(已打包,底部有地址,或可自己搜索下载)

1. aria2的windows版
2. ffmpeg的windows版
3. jquery文件
4. airaNg(推荐单文件版)

下好这些,就可以开始了

把这些放到一个文件夹里,出了aira2,其他最好都放统一目录,aria2可以放子目录(sham是放在子目录aira2里)

然后首先来写个启动aira2的,可以是bat,但是无法隐藏窗口,除非另外下工具,所以这里sham用的.vbs的形式,代码如下:

CreateObject("WScript.Shell").Run "aria2\aria2c.exe --conf-path=aria2\aria2.conf",0
CreateObject("WScript.Shell").Run "aria2\AiraNg.html",0

保存后,双击运行的话,就能运行aira2并在浏览器打开AriaNg,aria2c.conf的自行网上找或者看我前面的文章也有,AriaNg的话,因为aira2使用的默认配置,所以不用另外设AriaNg,当然也可自行设置

有了这些,一个替代迅雷的下载工具就好了

下面的是Sham用来下载视频用的,水平有限,只能手动到开发者工具里中去找m3u8文件地址后复制出来,等以后再研究怎样直接从网页抓

首先来写个html文件,通过jquery来分析m3u8文件中的ts列表并凭借成aria2的RPC能用的Json格式数据,完整代码如下:

<html>
    <head>
        <style>
            .tips{
                width: 80%;
                margin: 100px auto 10px;
                text-align: center;
                font-size:30px;
            }
            form{
                width: 100%;
                display: block;
            }
            .items{
                width: 80%;
                display: flex;
                flex-direction: column;
                text-align: center;
                margin:50px auto 10px;
            }
            .item{
                display: flex;
                flex-direction: row;
                width:100%;
            }
            .item div, .item input{
                margin: 10px auto;
                height:40px;
            
            }
            .title{
                width:100px;
                text-align: right;
            }
            .item input{
                width:80%;
            }
            .btn{
                display: block;
                margin: 10px auto;
                line-height: 40px;
                width:30%;
                font-size:20px;
                border-radius: 10px;
                text-align: center;
            }
        </style>
		<script src="jquery-3.6.0.min.js"></script>
    </head>
    <body>
        <div class="tips">输入名称和m3u8地址,下载ts文件到本地</div>
        <!-- get_ts_list.php   get_mp4.php -->

            <div class="items">
                <div class="item">
                    <div class="title">名称: </div>
                    <input type="text" id="name" name="name">
                </div>

                <div class="item">
                    <div class="title">m3u8地址: </div>
                    <input type="text" id="m3u8" name="m3u8">
                </div>
            </div>
			
            <input class="btn" type="submit" value="点击下载视频" onclick="to_get_m3u8()">

		
		<script>
			//点击下载按钮后执行
			function to_get_m3u8(){
				//先判断是否都填写了,没有就弹窗提醒
				if($('#name').val()=='' || $('#m3u8').val() ==''){
					alert("请填写:" +($('#name').val()=='' ? "视频名称!" :"") + ($('#m3u8').val()=='' ? "m3u8视频地址!" :""));
				}else{
					//执行下载
					var data = get_ts_file($('#m3u8').val());  
				}
			}
			
			//下载,其中会对传入的m3u8文件进行判断,获取到最终包含ts文件的m3u8文件,并执行下载
			function get_ts_file(m3u8_url){
				//获取网址信息,包含跟网址和m3u8文件网址路径
				var url_list = get_dir_url(m3u8_url);
				//通过jquery获取m3u8文件信息
				$.get(m3u8_url,function(data,status){
					//判断返回的数据中是否包含.m3u8,是,则再执行分析
					if(data.indexOf(".m3u8") != -1){  
						//将M3u8文件内容转成数组,用于循环操作
						var m3u8_contents = data.split(/[(\r\n)\r\n]+/);
						for(var i =0;i < m3u8_contents.length;i++){
							//如果文件数组中还有m3u8文件,则表示这个不是最终文件,继续分析
							if(m3u8_contents[i].indexOf(".m3u8") != -1){
								//如果m3u8文件地址带/,则使用网址根目录加这个地址,否则就使用m3u8地址加这个地址,这个用于一定程度上解决不同m3u8文件信息
								if(m3u8_contents[i].indexOf("/") != -1){	
									var real_m3u8_url = url_list['web_url'] + m3u8_contents[i];
								}else{
									var real_m3u8_url = url_list['m3u8_url'] + m3u8_contents[i];
								}								
								break; //跳出循环
							}
						}
						//再次分析
						get_ts_file(real_m3u8_url);
					}else{
						//这里是文件没有m3u8文件,表示为最终文件
						if(data.indexOf(".ts") != -1){
							var ts_lists = get_ts_list(url_list,data);
							var json_for_aria = json_for_aria2(url_list,ts_lists,m3u8_url);
							//console.log(ts_lists);
							download_file((json_for_aria));
						}else{
							//如最终文件还是没有ts信息,则无法执行这个下载程序了
							alert('该文件没有ts文件信息,请换一个m3u8下载!');
						}
					}
					
				}).fail(function () {
					   alert('无法获取m3u8文件信息!');
				});
			}
			
			
			//获取网址路径,用于拼接ts实际地址
			function get_dir_url(m3u8_url){
				var url_list = [];
				var m3u8_url_arr = m3u8_url.split('/')
				//这个是通过.splice来去掉m3u8文件名
				m3u8_url_arr = m3u8_url_arr.slice(0,m3u8_url_arr.length-1)
				//console.log(m3u8_url_arr)
				url_list['m3u8_url'] = m3u8_url_arr.join('/')+'/';
				url_list['web_url'] = m3u8_url_arr[0]+'//'+ m3u8_url_arr[2];
				return url_list;
			}
			
			//获取m3u8文件里的ts明细,生成ts_lists数组
			function get_ts_list(url_list,data){
				var m3u8_contents = data.split(/[(\r\n)\r\n]+/);
				var ts_lists = []; 
				//将最终包含ts文件列表的内容,通过循环判断,去除无用信息,生成ts列表数组
				m3u8_contents.forEach((item,index)=>{
				var ts_detail = [];
				if(item.indexOf(".ts") != -1){
					if(item.indexOf("/") != -1){  //判断ts地址有没有带/
						var ts_arr = item.split('/');
						ts_arr = ts_arr.slice(0,ts_arr.length-1)
						ts_detail['dir'] = ts_arr.join('/')+'/';
						ts_detail['file'] = url_list['web_url']+item;
					}else{
						ts_detail['dir'] = '';
						ts_detail['file'] = url_list['m3u8_url']+item;
					}
				  ts_lists.push(ts_detail);
				  }
				  //判断是否包含key信息
				  if(item.indexOf(".key") != -1){
					var key_arr = item.split('"');
					var temp_ts_key = key_arr[1];
					if(temp_ts_key.indexOf("/") != -1){  //判断ts地址有没有带/
						var ts_arr = temp_ts_key.split('/');
						ts_arr = ts_arr.slice(0,ts_arr.length-1)
						ts_detail['dir'] = ts_arr.join('/')+'/';
						ts_detail['file'] = url_list['web_url']+temp_ts_key;
					}else{
						ts_detail['dir'] = '';
						ts_detail['file'] = url_list['m3u8_url']+temp_ts_key;
					}
					ts_lists.unshift(ts_detail);
				  }
				})
				console.log(ts_lists)
				return ts_lists;
			}
			
			//将ts_lists数组通过循环历遍,拼接成用于aria2的json数据
			function json_for_aria2(url_list,ts_lists,m3u8_url){
				var aria2_json = '{"jsonrpc": "2.0", "id": 1,"method": "aria2.addUri","params":["token:",["'+ m3u8_url +'"],{"out": "index.m3u8","dir":"tslist/'+$('#name').val()+'/"}]},';
				for(var i = 0; i < ts_lists.length; i++){
					aria2_json += '{"jsonrpc": "2.0", "id": ' + (i+2) +',"method": "aria2.addUri","params":["token:",["'+ts_lists[i]['file']+'"],{"dir":"tslist/'+$('#name').val()+ '/' + ts_lists[i]['dir'] +'/"}]}'+ (i+1 == ts_lists.length ? '' :',')
				}
				return '['+aria2_json+']';
			}


			//执行下载
			function download_file(data){
				//console.log(data)
				$.ajax({
					url: "http://localhost:6800/jsonrpc",
					data: data,
					type: "post",
					//async: false,//false为同步
					dataType: "json",
					success: function(obj) {
						//console.log(obj)
						//这里放了ariang,添加jsonrpc之后,可以通过ariang查看下载进度,当然直接用ariang下载也方便,只是只能添加文件真实地址
						window.open("./aria2/AiraNg.html");
					},
					error:function (e) {
		          //返回500错误 或者其他 http状态码错误时 需要在error 回调函数中处理了 并且返回的数据还不能直接alert,需要使用
		          //$.parseJSON 进行转译    res.msg 是自己组装的错误信息通用变量  
						var res = $.parseJSON(e.responseText);
						console.log(res);
					}
				});
			}
		
		</script>
    
    </body>
</html>

保存成.html文件后,打开,就能看到输入名称和m3u8地址的表单,名称用于保存到本地时的文件夹命名,方便查找

填入之后,点下载,就会分析m3u8文件,如果里面还套了m3u8文件,会继续分析,直至找到包含ts文件的最终m3u8地址,然后再下载ts文件

这里要说明下,目前代码只能分析有ts文件的m3u8文件,如果里面没有套m3u8,或者最终没有没有ts文件,就下载不了了

另外m3u8里面套娃格式的话,只会获取第一个,目前无法判断分辨率选择

下载会同时下m3u8文件,key文件,并按m3u8文件里列出来的目录路径逐级新建文件夹后保存

在下载完成ts之后,如需要,可通过ffmpeg来进行合并,包括加密含有key的ts文件解密后合并成mp4

这里写了个bat文件,方便执行,打开运行后,会提示你输入前面下载的时候的名称,或者想要生成mp4的ts文件夹名称,回车后会执行ffmpeg合并操作,正常不会有问题

有一个特殊情况,如果ts文件存储的目录是在m3u8文件目录的子目录下,需要修改下m3u8里面的ts路径,批量替换,在每个ts路径前面加一个英文句号,即变成“./xxx/xxx/xx.ts”这样,包括.key文件路径也是一样,保存后再生成即可

新建一个文件,命名成xx.bat,保存后运行即可(保存在根目录,与ffmpeg文件一起)

特别注意下,文件格式编码设成ANSI,不然中文可能会乱码

@echo off
set /p name=请输入下载时填写的文件名,或tslist文件夹下的文件夹名,然后回车:
ffmpeg -allowed_extensions ALL -i tslist/%name%/index.m3u8 -c copy mp4/%name%.mp4
pause

当不想使用的时候,可通过bat来关闭aria2,代码如下

@echo off
echo Stopping aria2...
taskkill /F /IM aria2c.exe > nul
exit

最后附上下载链接:Aria2+ffmpeg+m3u8下载工具(windows版)-其它文档类资源-CSDN下载

一个在前往码农道路上走走停停的行政文员

 类似资料: