如何使用 Elixir/HTTPoison 或 Hackney 获取视频流?
How to get a video flow with Elixir/HTTPoison or Hackney?
我正在尝试使用 Elixir / HTTPoison 从摄像头获取流并将其转储到文件中。
Url 是 x.x.x.x/axis-cgi/mjpg/video.cgi?duration=1&resolution=320x240
使用 DHC 中的 url(Chrome 插件),我可以得到以下内容:
Response 200 OK
HEADERS Cache-Control: no-cache Pragma: no-cache Expires: Thu, 01 Dec
1994 16:00:00 GMT Connection: close Content-Type:
multipart/x-mixed-replace; boundary=myboundary X-Time-Offset:
62044.312573 pretty COMPLETE REQUEST HEADERS Accept: / Accept-Encoding: gzip, deflate, sdch
Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Content-Type: application/xml User-Agent: Mozilla/5.0 (Windows NT
6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Note: XHR automatically adds
headers like Accept, Accept-Language, Cookie, User-Agent, etc.
正文的原始格式向我展示了很多由 --myboundary 分隔的二进制 jpeg 图像。
--myboundary
Content-Type: image/jpeg
Content-Length: 11848
����JFIF�� W�u]7W�u]7�� �2�̎TY"��C
现在,我想尝试用 Elixir 得到同样的东西。
test "request headers from cam" do
options = [hackney: [basic_auth: {"login","password"}]]
{:ok, %HTTPoison.AsyncResponse{id: id}} = HTTPoison.get "http://x.x.x.x/axis-cgi/mjpg/video.cgi?duration=1&resolution=320x240",[], [stream_to: self, recv_timeout: :infinity, hackney: options]
assert_receive %HTTPoison.AsyncStatus{id: ^id, code: 200}, 1_000
end
我确实有以下回复,
1) test request headers from cam (NewsequenceTest)
test/newsequence_test.exs:9
No message matching %HTTPoison.AsyncStatus{id: ^id, code: 200} after 1000ms.
The following variables were pinned:
id = #Reference<0.0.3.125>
Process mailbox:
%HTTPoison.AsyncStatus{code: 401, id: #Reference<0.0.3.125>}
%HTTPoison.AsyncHeaders{headers: [{"Date", "Wed, 31 Aug 2016 06:47:00 GMT"}, {"Accept-Ranges", "bytes"}, {"Connection", "close"}, {"WWW-Authenticate", "Digest realm=\"AXIS_ACCC8E545922\", nonce=\"0000fa64Y50235919055a42f91d3dea744b10d2dab9653\", stale=FALSE, qop=\"auth\""}, {"WWW-Authenticate", "Basic realm=\"AXIS_ACCC8E545922\""}, {"Content-Length", "189"}, {"Content-Type", "text/html; charset=ISO-8859-1"}], id: #Reference<0.0.3.125>}
%HTTPoison.AsyncChunk{chunk: "<HTML><HEAD><TITLE>401 Unauthorized</TITLE></HEAD>\n<BODY><H1>401 Unauthorized</H1>\nYour client does not have permission to get URL /axis-cgi/mjpg/video.cgi from this server.\n</BODY></HTML>\n", id: #Reference<0.0.3.125>}
%HTTPoison.AsyncEnd{id: #Reference<0.0.3.125>}
stacktrace:
test/newsequence_test.exs:12: (test)
我在没有基本身份验证的情况下尝试了相同的结果。
我还不明白这个身份验证错误是怎么回事。
当然我误解了一些东西,有人可以在这个问题上启发我吗?
亲切的问候,
皮埃尔
所以这里的问题是代码正在调用:
HTTPoison.get(..., [], [..., hackney: [hackney: [basic_auth: {"login","password"}]]])
而不是:
HTTPoison.get(..., [], [..., hackney: [basic_auth: {"login","password"}]])
导致 hackney
忽略它们,因为它试图获取 opts[:hackney][:basic_auth]
等,这些都是 nil
。
修复方法是替换:
options = [hackney: [basic_auth: {"login","password"}]]
和
options = [basic_auth: {"login","password"}]
我正在尝试使用 Elixir / HTTPoison 从摄像头获取流并将其转储到文件中。 Url 是 x.x.x.x/axis-cgi/mjpg/video.cgi?duration=1&resolution=320x240
使用 DHC 中的 url(Chrome 插件),我可以得到以下内容:
Response 200 OK
HEADERS Cache-Control: no-cache Pragma: no-cache Expires: Thu, 01 Dec 1994 16:00:00 GMT Connection: close Content-Type: multipart/x-mixed-replace; boundary=myboundary X-Time-Offset: 62044.312573 pretty COMPLETE REQUEST HEADERS Accept: / Accept-Encoding: gzip, deflate, sdch Accept-Language: fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4 Content-Type: application/xml User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36 Note: XHR automatically adds headers like Accept, Accept-Language, Cookie, User-Agent, etc.
正文的原始格式向我展示了很多由 --myboundary 分隔的二进制 jpeg 图像。
--myboundary
Content-Type: image/jpeg
Content-Length: 11848
����JFIF�� W�u]7W�u]7�� �2�̎TY"��C
现在,我想尝试用 Elixir 得到同样的东西。
test "request headers from cam" do
options = [hackney: [basic_auth: {"login","password"}]]
{:ok, %HTTPoison.AsyncResponse{id: id}} = HTTPoison.get "http://x.x.x.x/axis-cgi/mjpg/video.cgi?duration=1&resolution=320x240",[], [stream_to: self, recv_timeout: :infinity, hackney: options]
assert_receive %HTTPoison.AsyncStatus{id: ^id, code: 200}, 1_000
end
我确实有以下回复,
1) test request headers from cam (NewsequenceTest)
test/newsequence_test.exs:9
No message matching %HTTPoison.AsyncStatus{id: ^id, code: 200} after 1000ms.
The following variables were pinned:
id = #Reference<0.0.3.125>
Process mailbox:
%HTTPoison.AsyncStatus{code: 401, id: #Reference<0.0.3.125>}
%HTTPoison.AsyncHeaders{headers: [{"Date", "Wed, 31 Aug 2016 06:47:00 GMT"}, {"Accept-Ranges", "bytes"}, {"Connection", "close"}, {"WWW-Authenticate", "Digest realm=\"AXIS_ACCC8E545922\", nonce=\"0000fa64Y50235919055a42f91d3dea744b10d2dab9653\", stale=FALSE, qop=\"auth\""}, {"WWW-Authenticate", "Basic realm=\"AXIS_ACCC8E545922\""}, {"Content-Length", "189"}, {"Content-Type", "text/html; charset=ISO-8859-1"}], id: #Reference<0.0.3.125>}
%HTTPoison.AsyncChunk{chunk: "<HTML><HEAD><TITLE>401 Unauthorized</TITLE></HEAD>\n<BODY><H1>401 Unauthorized</H1>\nYour client does not have permission to get URL /axis-cgi/mjpg/video.cgi from this server.\n</BODY></HTML>\n", id: #Reference<0.0.3.125>}
%HTTPoison.AsyncEnd{id: #Reference<0.0.3.125>}
stacktrace:
test/newsequence_test.exs:12: (test)
我在没有基本身份验证的情况下尝试了相同的结果。
我还不明白这个身份验证错误是怎么回事。 当然我误解了一些东西,有人可以在这个问题上启发我吗?
亲切的问候,
皮埃尔
所以这里的问题是代码正在调用:
HTTPoison.get(..., [], [..., hackney: [hackney: [basic_auth: {"login","password"}]]])
而不是:
HTTPoison.get(..., [], [..., hackney: [basic_auth: {"login","password"}]])
导致 hackney
忽略它们,因为它试图获取 opts[:hackney][:basic_auth]
等,这些都是 nil
。
修复方法是替换:
options = [hackney: [basic_auth: {"login","password"}]]
和
options = [basic_auth: {"login","password"}]