如何通过 youtube-dl 接收的数据在客户端创建视频文件?
Posted
技术标签:
【中文标题】如何通过 youtube-dl 接收的数据在客户端创建视频文件?【英文标题】:How to create video file in client from data receiving by youtube-dl? 【发布时间】:2020-11-06 01:52:48 【问题描述】:我正在通过在后端使用 youtube-dl 和 php 构建一个小的 youtube 下载器。 当用户提交 youtube 视频 url 时,php 正在执行 youtube-dl.exe 并将视频数据直接传递给客户端,因为我避免它在后端下载视频,而不是再次将其下载到前端。
这里是我将流直接传递给客户端的 php 代码:
header("Content-Disposition: attachment; filename=\"...\"" );
header("Content-Type: application/octet-stream");
passthru("$pathToYouTubedlExe -o - $youtube_video_url");
到达客户端的视频数据看起来像这样,它是一个字符串:
ftypmp42 isommp42 �moov lmvhd � �B� �BX �@ iods O��)� �trak \tkhd �B 2 @ � h $edts elst 2 �mdia mdhd � �B $ � � � � � y � � 3 � � Y � � � 0 > ^ � � [ X � � � 3 ! % � y 6 3 $stco �z� �p kx �k �trak \tkhd ���B� �B �@ =mdia mdhd � �B �B �D �U� Lhdlr soun IsoMedia 文件由 Google 制作,5 -11-2011 �minf smhd $dinf dref url �stbl istsd Ymp4a �D 5esds ' @ Q ��� stts f 4stsc �stsz f + % # & # ! " ! 8 ! & 4 - # ! = 3 6 Q O � � " " % #" ! % 5 Q F F F ? 8 6 $stco b� �T6 �1 �B �mdat +e����ϔP �Ў�j�� �Dٸ����a &X...m... ��=~��xwU�1��Ć́\��H���k�Ы ���.�(�ثg�b��������?�����>��A�=�)freeIsoMedia 文件由 Google 生成
这是到达客户端的数据。 我的问题是如何为该特定视频创建视频文件,例如 mp4 或 webm 或任何其他可用扩展?
我用 blob 尝试过:
let response = await axios.get("http://localhost/youtube-dl/index.php",
params:
download_video:JSON.stringify(this.videoInfo)
, responseType:"application/octet-stream" );
const props = type: "octet/stream";
const props2 = type: "video/mp4"; / <<---- not working too
let file;
try
file = new File([response.data],"test.mp4", props);
catch (e)
file = new Blob([response.data], props);
var fileURL = window.URL.createObjectURL(file);
let fileLink = document.createElement("a");
fileLink.href = fileURL;
fileLink.setAttribute("download","test.mp4")
document.body.appendChild(fileLink);
fileLink.click();
我尝试用该视频数据创建一个 json 对象,希望可能有一个带有 JSON.parse(response.data) 的对象 json 结构,但它不起作用。
【问题讨论】:
【参考方案1】:响应数据应该已经是二进制数据,尽管您似乎正在尝试将字节值显示为文本。您可以尝试下面的代码,或者使用 FileReader API 作为另一种保存方法。
试试:
var fileLink = document.createElement('a');
fileLink.download = 'test.mp4';
let blob = new Blob([response.data], type: 'octet/stream');
fileLink.href = URL.createObjectURL(blob);
fileLink.click();
URL.revokeObjectURL(fileLink.href);
编辑:
查看this thread 是否有助于 Axios 方面。 我对 Axios 不熟悉,但 online example 提供了一个线索,它应该如下所示:
var vid_url = 'https://www.yoursite.com/yourPHP_Passthru_Script.php';
axios.get(vid_url,
responseType: 'arraybuffer'
)
.then(function (response)
res.type('application/octet-stream');
res.end( response.data, 'binary' );
);
【讨论】:
感谢您的回答,但您的示例也不起作用。你是对的 response.data 作为字符串到达。我怎样才能使它成为二进制文件。我在 axios 请求中将响应类型定义为八位字节/流,但它仍然作为字符串到达。我尝试使用客户端中的一种方法使其二进制化,但如果视频有点大,它会阻塞浏览器。你有任何其他的想法如何使它像二进制? 你的 PHPheader
没问题。我对 Axios 不熟悉,但 some research 说试试:responseType: 'arraybuffer'
。如果仍然失败,那么首先将props
更改为type: "application/octet-stream";
...另一个最后的选择是忘记Axios,只使用标准XHR 请求从PHP 获取字节。以上是关于如何通过 youtube-dl 接收的数据在客户端创建视频文件?的主要内容,如果未能解决你的问题,请参考以下文章
youtube-dl:通过忽略 archive.txt 中指定的视频,将 youtube 视频 info.json 下载到播放列表中
Youtube-dl - 提取元数据/json 信息到文本文件
通过 php 使用 youtube-dl 时出现 Python ImportError