找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 33116|回复: 7

[文本处理] [已解决]求解自定义协议(URL Protocol)传参被URI编码后的URI解码问题

[复制链接]
发表于 2018-12-4 09:52:21 | 显示全部楼层 |阅读模式
楼主是个爱偷懒的奇葩,希望在不依赖于 Chrome 插件的情况下,楼主企图利用自定义协议去启动本地的 FFMPEG 来保存 M3U8 的视频。

FFmpeg自定义协议注册表
  1. Windows Registry Editor Version 5.00

  2. [HKEY_CLASSES_ROOT\ffmpeg]
  3. @="URL:ffmpeg Protocol"
  4. "URL Protocol"=""

  5. [HKEY_CLASSES_ROOT\ffmpeg\shell]

  6. [HKEY_CLASSES_ROOT\ffmpeg\shell\open]

  7. [HKEY_CLASSES_ROOT\ffmpeg\shell\open\command]
  8. @=""D:\\Software_Temp\\M3U8 Downloader 0.1.1\\Tools\\ffmpeg.bat" "%1""
复制代码
Bat 内容
  1. @echo off
  2. cd /d %~p0
  3. for /f "tokens=1,2 delims=," %%i in (%1) do (
  4.         set url=%%i
  5.         set filename=%%j
  6. )

  7.         ffmpeg.exe -i "%url:~9%" -c copy -y -bsf:a aac_adtstoasc "F:\Download_M3U8\%filename%.mp4"
  8. rem ffmpeg.exe" -i "%%i" -c copy -y -bsf:a aac_adtstoasc "%%j.mp4"
  9. echo.
  10. echo 视频下载完成
  11. pause
复制代码
但 URL Protocol 传送的参数会进行URI编码,导致无法使用传送的中文内容来保存

如:
  1. ffmpeg://www.baidu.com,百度
复制代码
得到的是
  1. ffmpeg://www.baidu.com,%E7%99%BE%E5%BA%A6
复制代码
我想尝试改为使用 JS 来运行ffmpeg,但是 JS 似乎无法得到传参的内容,VBS 没有URI的解码函数。

求大神支招,该如何对这个 URI 进行解码,并作为文件名输出。

JS、VBS、Bat 三种方案都可以,混编也行。

纯 JS 解决方案
注册表
  1. [HKEY_CLASSES_ROOT\ffmpeg]
  2. @="URL:ffmpeg Protocol"
  3. "URL Protocol"=""

  4. [HKEY_CLASSES_ROOT\ffmpeg\shell\open\command]
  5. @="wscript -nologo -e:jscript "D:\\Software_Temp\\M3U8 Downloader 0.1.1\\Tools\\ffmpeg.js" "%1""
复制代码
最后解决方案使用纯 JS 来进行
原来之前以为 Arguments 是 WSH 的属性,所以一直没有得到参数。
  1. var wsh=new ActiveXObject("WScript.Shell");
  2. //获得 URL Protocol 参数,并进行数组分割,WScript.Arguments的下标使用圆括号,数组为方括号
  3. var Args=WScript.Arguments(0).split(",");

  4. var ProgramFloder=WScript.ScriptFullName.replace(/[^\\]+$/,''),
  5.         Program=ProgramFloder+"ffmpeg.exe",
  6.         M3U8Url=Args[0].replace(/^ffmpeg:\/\//i,''),
  7.         webTitle=decodeURIComponent(Args[1]).replace(/[\/|*?"<>:]/gm,'_');
  8. wsh.Run("""+Program+"""+" -i "+M3U8Url+" -c copy -y -bsf:a aac_adtstoasc F:\\Download_M3U8\"+webTitle+".mp4");
复制代码

评分

参与人数 1PB +2 收起 理由
Batcher + 2 感谢给帖子标题标注[已解决]字样

查看全部评分

发表于 2018-12-4 10:47:37 | 显示全部楼层
本帖最后由 523066680 于 2018-12-4 10:59 编辑

很久没用过VBS了,方案应该有,只是我不知道。
python 做这个事情很简单。Perl里面有个 URI::Escape 处理这个,也可以不用URI::Escape,自己转。

举个栗子,两种方式
  1. use Encode;
  2. use URI::Escape;

  3. my $s1 = 'ffmpeg://www.baidu.com,%E7%99%BE%E5%BA%A6';
  4. $s1 =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg;
  5. printf "%s\n", encode('gbk', decode('utf8', $s1));

  6. my $s2 = 'ffmpeg://www.baidu.com,%E7%99%BE%E5%BA%A6';
  7. printf "%s\n", encode('gbk', decode('utf8', uri_unescape($s1)));

复制代码

评分

参与人数 1技术 +1 收起 理由
极品小猫 + 1 乐于助人

查看全部评分

发表于 2018-12-4 11:06:55 | 显示全部楼层
 楼主| 发表于 2018-12-4 11:32:54 | 显示全部楼层
纯 JS 解决方案
注册表
  1. [code][HKEY_CLASSES_ROOT\ffmpeg]
  2. @="URL:ffmpeg Protocol"
  3. "URL Protocol"=""

  4. [HKEY_CLASSES_ROOT\ffmpeg\shell\open\command]
  5. @="wscript -nologo -e:jscript "D:\\Software_Temp\\M3U8 Downloader 0.1.1\\Tools\\ffmpeg.js" "%1""
复制代码
[/code]

最后解决方案使用纯 JS 来进行
原来之前以为 Arguments 是 WSH 的属性,所以一直没有得到参数。
  1. var wsh=new ActiveXObject("WScript.Shell");
  2. //获得 URL Protocol 参数,并进行数组分割,WScript.Arguments的下标使用圆括号,数组为方括号
  3. var Args=WScript.Arguments(0).split(",");

  4. var ProgramFloder=WScript.ScriptFullName.replace(/[^\\]+$/,''),
  5.         Program=ProgramFloder+"ffmpeg.exe",
  6.         M3U8Url=Args[0].replace(/^ffmpeg:\/\//i,''),
  7.         webTitle=decodeURIComponent(Args[1]).replace(/[\/|*?"<>:]/gm,'_');
  8. wsh.Run("""+Program+"""+" -i "+M3U8Url+" -c copy -y -bsf:a aac_adtstoasc F:\\Download_M3U8\"+webTitle+".mp4");
复制代码
 楼主| 发表于 2018-12-4 11:33:42 | 显示全部楼层
回复 2# 523066680


    已使用纯 JS 解决问题,这个问题如果使用第三方的方式确实很好搞
发表于 2018-12-4 11:33:50 | 显示全部楼层
ffmpeg.js
  1. if (WScript.Arguments.length === 0) WScript.Quit(1);
  2. var a = WScript.Arguments(0).split(',');
  3. var url = a[0];
  4. var filename = a[1] + '.mp4';
  5. var fileDir = 'F:\\Download_M3U8';
  6. var cmd = 'ffmpeg.exe -i "' + url.slice(9) + '" -c copy -y -bsf:a aac_adtstoasc "' + fileDir + '\\' + filename + '"';
  7. WScript.CreateObject('WScript.Shell').Run(cmd, 1, true);
  8. WScript.CreateObject('Scripting.FileSystemObject').GetFile(fileDir + '\\' + encodeURI(filename)).Name = filename;
  9. WScript.Echo('视频下载完成');
复制代码

评分

参与人数 1技术 +1 收起 理由
极品小猫 + 1 乐于助人

查看全部评分

 楼主| 发表于 2018-12-4 11:34:30 | 显示全部楼层
回复 3# Batcher


    感谢帮助,不过希望尽量不使用第三方命令来完成。现在使用纯 JS 来解决问题了
发表于 2018-12-4 13:02:34 | 显示全部楼层
回复 7# 极品小猫


    嗯,哪两个帖子里面也是用的 encodeURIComponent decodeURIComponent
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-19 10:52 , Processed in 0.020337 second(s), 8 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表