【问题标题】:How to get a snapshot of network video stream with curl in c/c++ in windows?如何在 Windows 中使用 c/c++ 中的 curl 获取网络视频流的快照?
【发布时间】:2010-10-13 06:37:53
【问题描述】:

准确的媒体类型,然后以正确的扩展名保存捕获的图像?

【问题讨论】:

  • 等一下 - 你的视频是什么格式的?

标签: c++ windows curl


【解决方案1】:

当浏览器想要播放视频并开始文件传输时,通常会向服务器(保存视频流)发送一个 http GET 请求,但是这种握手可能会根据到您正在与之协商的服务器。

下面是一个简短的代码 sn-p,它显示了当您拥有文件的完整 url 时如何设置 curl 和下载文件:

#include <curl/curl.h>
#include <stdio.h>

void get_page(const char* url, const char* file_name)
{
  CURL* easyhandle = curl_easy_init();

  curl_easy_setopt( easyhandle, CURLOPT_URL, url ) ;

  FILE* file = fopen( file_name, "w");

  curl_easy_setopt( easyhandle, CURLOPT_WRITEDATA, file) ;

  curl_easy_perform( easyhandle );

  curl_easy_cleanup( easyhandle );
}

int main()
{
  get_page( "http://blog.stackoverflow.com/wp-content/themes/zimpleza/style.css", "style.css" ) ;

  return 0;
}

像 youtube 这样的网站不会轻易提供视频的 URL,甚至可能会将您重定向到另一个 html 页面,您可以解析该页面以找到组装视频完整 URL 所需的神奇信息。很久以前我写了一个小 bash 脚本来自动化查找 youtube 的视频 URL 和下载视频的过程。我知道它不再起作用了,所以我将其粘贴仅用于教育目的:

if [ -z "${1}" ]
then
    echo 'Error !!! Missing URL or video_id !!!'
    exit 1
fi

URL="http://www.youtube.com"

# Retrieve video_id from url passed by the user
VAR_VIDEO_ID="${1/*=}"    

# Retrive t variable located in var swfHTML (javascript)
VAR_T=$(wget -qO - $URL/watch?v=$VAR_VIDEO_ID 2>&1 | perl -e 'undef $/; <STDIN> =~ m/&t=([^&]*)&/g; print "$1\n"';)

# Assemble magical string
FLV_URL="$URL/get_video?video_id="$VAR_VIDEO_ID"&t="$VAR_T"=&eurl=&el=detailpage&ps=default&gl=US&hl=en"

# Download flv from Youtube.com. Add 2>&1 before wget cmd to suppress logs
WGET_OUTPUT=$(wget $FLV_URL -O $VAR_VIDEO_ID.flv)

# Making sure the download went okay
if [ $? -ne 0 ]
then
    # wget failed
    echo -e 1>&2 $0: "!!! ERROR: wget failed !!!\n"
    rm $VAR_VIDEO_ID.flv
    exit 1
fi

为了回答您的第二个问题,我相信要识别文件/媒体类型,您必须下载视频流的第一个字节,因为它包含文件头,然后检查它是否已知 file signatures。例如,FLV 文件的第一个字节应该是:

46 4C 56 01

编辑:

下载视频流并没有想象中的那么不同。您需要告诉 curl 您有自己的方法来保存流数据,可以通过以下方式指定:

curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, cb_writer);
curl_easy_setopt(curl_hndl, CURLOPT_WRITEDATA, url_data);

其中 *cb_writter* 是新数据到达时 curl 将调用的回调。 Check the documentation 回调选项 了解有关这些函数的更多信息。

如果您需要完整示例,您可以check this thread

还有一点,如果您正在使用M-JPEG streams,您应该看看cambozola 的实现。

【讨论】:

  • 我知道如何用 curl 下载文件,但如果你处理的是视频流,比如 MJEPG 流,那就完全不同了。
  • @Alan 更新了我的答案,我还参考了一个工作示例。
猜你喜欢
  • 2011-03-01
  • 1970-01-01
  • 2011-05-16
  • 2020-11-12
  • 2013-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多