如何从XHR下载流媒体视频

8
我想从一个使用flowplayer的网站下载视频。当我检查元素时,会得到类似下面这样的内容: enter image description here 因此我们可以说这个视频是通过xhr流式传输的。有没有办法从这些文件中获取完整的视频?我尝试过Flash Player Downloader,它会下载.mp4文件,但是这个文件已经损坏了,也无法通过一些工具进行修复。

有关这个的一些新闻吗?我也有类似的问题 :( - yhoyo
2个回答

6
我没有确切的答案,但我也尝试下载过这样的碎片流,那真是非常痛苦。以下是帮助我的解决方案:https://superuser.com/questions/1204497/download-all-m4s-files-of-a-mpeg-dash-stream

思路就是从初始文件IS.mp4中获取流的URL。随后所有的部分,编号为000000.m4s, 000001.m4s, 000002.m4s, ...与IS.mp4共享相同的位置。

生成所有部分的下载链接,下载并合并它们,可以很容易地编写脚本实现,如链接的帖子所示:

echo "IS.mp4" >"links.txt"
seq -f "%06g.m4s" 0 394 >>"links.txt"
wget -i "links.txt" -O "audio.mp4" -B "http://80.188.78.212/aa/ffc8a55fe6f203b0bffecb73efacb69b/1494953435522/eda9c6f7b1e3de68db8e3e5dc0d14fc7/dna-61924494877285694-pc/1002-1502/"

您需要下载所有部分,包括IS.mp4,并将它们合并为一个文件。有时您还需要以这种方式下载音轨。在获取了视频和音轨之后,请将它们合并到一个容器中。

1
你最终是如何解决这个问题的?你说来自SuperUser的答案有所帮助,但最终的解决方案是什么?你是如何从TAB /会话中访问.xhr文件的? - Radu Gheorghiu
在浏览器中,我使用了上下文菜单中的“检查元素”,然后进入了网络监视器选项卡,并选择了XHR作为过滤类型。 - fleetingbytes

0

嗯,我有一个半手动的解决方案,可以确保较小的视频文件正常工作:

  1. 在Firefox(我的版本是75.0)中打开视频页面,不要开始播放。
  2. 打开网络面板(F12)。
  3. 刷新视频页面。滚动到播放器并开始播放。
  4. 等待视频结束。同时不要触摸浏览器的控件。
  5. 点击网络面板右上角的“HAR”按钮。
  6. 将整个网络转储保存为HAR文件。

1分钟的视频大约是10 MB的JSON编码文本。现在,您应该编写一个脚本,从保存的网络转储中解码和连接响应字节范围(HTTP 206)。以下是示例PHP代码:

// for demonstration purposes only // no checks // at all //

$har = $argv[1]; // HAR input file //
$nam = $argv[2]; // video name from URL //
$out = $argv[3]; // MP4 output file //

$text = file_get_contents($har);
$json = json_decode($text);

$map = array(); // range map //
foreach ($json->log->entries as $e) {
  if (!is_object($e) OR !property_exists($e, 'request') OR !property_exists($e, 'response')) {
    continue;
  }
  if ($e->request->method != 'GET') {
    continue;
  }
  if (strpos($e->request->url, $nam) === false) {
    continue;
  }
  if ($e->response->status != 206) {
    continue;
  }
  if ($e->response->content->encoding != 'base64') {
    continue;
  }
  foreach ($e->response->headers as $h) {
    if ($h->name == 'content-range' AND 0 < preg_match('/^bytes ([0-9]+)-([0-9]+)\\/([0-9]+)$/', $h->value, $match)) {
      $map[$match[1]] = array(
        'in' => $match[1],
        'out' => $match[2],
        'text' => $e->response->content->text,
      );
      break;
    }
  } // foreach //
} // foreach //

file_put_contents($out, '');
ksort($map);
$err = 0;
$j = -1;
foreach ($map as $k => $v) {
  $i = $j + 1;
  $j = $v['out'];
  $part = base64_decode($v['text']);
  file_put_contents($out, $part, FILE_APPEND);
} // foreach //

我刚刚成功保存了一些短视频。它们的时长在4到8分钟不等。输出文件是一个MP4流,所以我将其转码为MKV格式:

ffmpeg -i har2bin.mp4 -c copy -y har2bin.mkv

现在,您可以使用VLC播放器播放MKV文件。


我最近在Chrome中尝试了一下,它可以正常工作。此外,Firefox会将XHR响应截断为1M,而Chrome则不会。 - ThatsMe
1
我认为你可以在Firefox的about:config中更改或禁用限制。将devtools.netmonitor.responseBodyLimit设置为0可禁用限制。 - Kit Roed
感谢您提供的信息。 - ThatsMe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接