首页 > 解决方案 > 如何通过 youtube-dl 接收的数据在客户端创建视频文件?

问题描述

我正在通过在后端使用 youtube-dl 和 php 构建一个小的 youtube 下载器。当用户提交 youtube 视频 url 时,php 正在执行 youtube-dl.exe 并将视频数据直接传递给客户端,因为我避免它在后端下载视频,而不是再次将其下载到前端。

这里是 iam 将流直接传递给客户端的 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 < �U' -hdlr 视频 VideoHandler �minf vmhd $dinf dref url dstbl �stsd �avc1 �h HH �� .avcCB��� gB����� ��b� h�<� btrt + ]X *� stts C stss = @stsc stsz C + 7 / � � � 2 : � � � N � t �J � � � F � 0 # ? Q �<br /> $ � � � � � � 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 - # != % � 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 - # != % � 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 - # != @Q �� stts f 4stsc �stsz f + % # & # ! " !8 !& 4 - # != @Q �� stts f 4stsc �stsz f + % # & # ! " !8 !& 4 - # !=
3 6 QO � � " " % # " ! % 5 QFFF ? 8 6 $stco b� �T6 �1 �B �mdat +e����ϔP �Ў�j�� �Dٸ����a &X� ��m�����~�J�R��jf�NMB�T�&h�Yd!���䲭�Ԙ +c�Q�HOj�̑Rv��U�,����L ��=~��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 结构,但它不起作用。

标签: javascriptvideomp4h.264youtube-dl

解决方案


响应数据应该已经是二进制数据,尽管您似乎正在尝试将字节值显示为文本。您可以尝试下面的代码,或者使用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);

编辑

看看这个线程是否有助于 Axios 方面。我不熟悉 Axios,但一个在线示例提供了一个线索,它应该如下所示:

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' );
});

推荐阅读