你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

全网首发,用STM32F429实现的网页摄像头mjpeg-stream  

[复制链接]
shanji 发布时间:2019-4-1 17:58
本帖最后由 shanji 于 2019-4-27 09:03 编辑
0 k) ^: M$ G0 A: u/ j1 [' b& ]* p9 r
https://www.stmcu.org.cn/module/forum/thread-609701-1-1.html/ K: n1 q0 D/ l4 G+ S( a! d8 w+ }
距上次分享了个网络摄像头的示例也有一段时间了,用的裸TCP协议,这次来玩玩不同的花样,网页摄像头mjpeg-stream传输,用HTTP协议。网上搜了下,清一色的在Linux下实现的,在单片机上实现的还真没找到,为了玩起来,只能琢磨linux下的代码。
6 D! `/ ~, \  u6 H        一、先把网页做出来
: D/ H- K+ L2 z& l4 ^( Y- s' D  i      网页端的实现比较简单,用img标签,例:
; v2 m& C- }* O5 |# m<html>
5 b5 J  j; L8 J+ M3 {) N      <head>& }+ B0 |' B, t2 ?- L  _5 ~
      </head>1 V4 i; x" v4 C( b8 M
      <body>
. V, a) O" D, d- i; n      <img src="http://192.168.1.199:80/?stm32=mjpeg">,此处的ip指的是服务器的ip。% L( Y5 p$ M- m( C  r! `
      </body>& G: L+ ?4 p& w, O' Q
</html>
: w+ [# ]8 n# B+ A. u- c  K      二、 服务端的代码实现7 f; c: n0 g  W1 y+ j  j" X
      要在网页上看到不断刷新的图片,服务端需要发送如下的相应包9 I- L; E! K! e0 G
     HTTP/1.1 200 OK\r\n
- l+ I! ^) Q! w$ N/ t
/ J  O6 S  M, s) W3 t! }& V
     Content-Type: multipart/x-mixed-replace;boundary=xxxxxxxx\r\n\r\n   //boundary后面的字段自行定义
     关于multipart/x-mixed-replaceboundary网上有很多专业解释,我就不copy了,知道怎么用它就对了。
    要发送图片时的数据包格式是
  --xxxxxxxx\r\n
   Content-Type: img/jpeg\r\n
   Content-Length: 2048\r\n\r\n  //此帧图片的大小
   循环发送这样的数据包给网页,网页上就能看到不断刷新的画面了      
   有了上面的基础,就可以开始码代码。
    关键代码:
     程序中使用了RT-Therad RTOS,用socket编程。
  1. **! A7 o$ ?! H1 D+ p5 ?
  2.   * @brief 开始发送流
    / E' o( @1 T5 ~4 j
  3.   * @param  client,count0 ~6 ~! K. C6 s
  4.   * @retval None
    ! k" p  D1 ^' Y/ e! X: d
  5.   */
    ; M+ v4 P# m+ p0 T( m# d4 {
  6. HTTP_STA HTTP_Streamer_Start(int client,u8 count)0 v2 x: ?  [5 j. {
  7. {        ( D# u4 ]& s$ O6 G% @4 @& K# L
  8.     int frame_size=0;, z2 Y5 t) `! Y* P4 ?
  9.    uint16_t haed_len=0;
    7 v+ B5 M8 q1 w8 h7 D1 Z" i
  10.    sprintf(buffer, "HTTP/1.1 200 OK\r\n"\
    , G3 Q( W; l- L
  11.    "Connection: Keep-Alive\r\n"\0 [" }! b3 X3 P) P5 J0 l3 @, r
  12.    "Server: MJPG-Streamer/0.2\r\n"\
    : ~, a) G4 D/ I  p% m. i4 M
  13.    "Cache-Control:no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0\r\n"\
    % m6 p* I: v* d- t: K& ]
  14.    "Pragma:no-cache\r\n"\4 y, I* ?6 Z3 `# R) R- _
  15.    "Expires:WED, 23 Jan 2019 01:00:00 GMT\r\n"\- A. r. c. V& {
  16.    "Content-Type: multipart/x-mixed-replace;boundary=openmcu\r\n\r\n"\5 c( t) u% n2 @. y) ~
  17.    "--openmcu\r\n"); + w7 x$ W" A" u1 j# a
  18.                               7 W+ a# y! M# `, @7 h
  19.     haed_len=strlen(buffer);( W( p  f% u1 b3 z- j
  20.    //printf("\r\n%s\r\n",buffer);
    # \) r7 Q: e+ ^8 P4 k: F
  21.    if(send(client, buffer,haed_len, 0)==-1)" u6 {0 B, Z" s) @6 h
  22.    {
    - j6 ?1 d2 y- e) ]
  23.       return HTTP_FAIL;
      b- Q# r, _% u9 p
  24.    }, n  W9 K2 N: M" m
  25.   #if USE_CAMERA: T# L# c! C8 k8 N9 d& y+ x0 {0 U
  26.   frame_size=jpeg_data_len(); 1 W4 q! q/ x( `3 g- c8 D% [
  27.   if(frame_size==0) return HTTP_FAIL;
    ! @' D" E; z: z2 r* C0 Y$ s
  28.   #else
    ) v* @9 u5 h1 [
  29.   if(count==0)' }8 C2 ^  ], c5 {4 F) p" w, B
  30.   frame_size=sizeof(cam_data);" g6 D3 K7 {$ B; J4 s6 j
  31.   else if(count==1)
    : g% ]$ ~$ A( |$ [
  32.   frame_size=sizeof(cam_data2);) }8 l' K7 C# [, ]4 s' ^& v
  33.   #endif            J; \3 O8 v/ ^
  34.   haed_len=strlen(buffer);
    6 x/ |6 U" d& d. e$ s- U6 t* M' g

  35. . Q2 V: {( W, j/ u$ u
  36.   sprintf(buffer, "Content-Type: image/jpeg\r\n"\
    $ @! q' \3 U1 n$ I( k
  37.   "Content-Length: %d\r\n\r\n", frame_size);
    ! V8 @# Y; ?& {" f' i1 g
  38.   printf("\r\n%s\r\n",buffer);
    " `) @" @. @; r% O: q) a8 ]
  39.   haed_len=strlen(buffer);
    3 l7 h: d, H" f" ]. n5 p
  40.   if(send(client, buffer,haed_len, 0)==-1)
    - c" X7 h) ~  D" P! i3 P; G
  41.   {( ^# z3 E. X; d7 B3 i
  42.      return HTTP_FAIL;
    6 G( ^% z( l* F2 B1 q
  43.    }- ~! \. H$ C0 E/ S1 }
  44.   #if USE_CAMERA: B2 u& A9 G$ S& t- ]% J% F; o8 v7 q
  45.   memcpy(&buffer[haed_len],(char*)ptr,frame_size);- y9 p$ U: C' D+ E( Y: K" N% S2 l
  46.   #else
      L$ ]5 v# e9 L( L+ j0 X
  47.   if(count==0)
    6 ?0 p+ O  V+ {' A8 K  U! T- ^
  48.   memcpy(&buffer[haed_len],(char*)cam_data,frame_size);
      i0 d- n% c3 ]% w$ s8 y5 W! c
  49.   else if(count==1)
    1 t& r3 C0 a; W, o) G6 ?' X( F
  50.   memcpy(&buffer[haed_len],(char*)cam_data2,frame_size);0 z- V/ D! u6 ?
  51.   #endif                 
    , S2 S6 n/ R  U! h* G
  52.   if(send(client, &buffer[haed_len],frame_size, 0)==-1). E8 p# v. p: E. R
  53.   {! i4 P& @  z$ H" y! J5 d; x8 j2 n
  54.      return HTTP_FAIL;
    1 N1 D6 F* G/ O8 T! U
  55.   }
    - q& [4 b6 O8 g  b8 [/ b4 ~
  56.   #if USE_CAMERA
    5 T. F# A$ G% `' f8 \/ H# g
  57.        newframe=0;  
    5 }' x: z8 e2 ]! @3 T4 B
  58.        cam_start();           Q2 V6 S  i% N# V+ r8 _
  59.   #endif
    3 ?% g# L1 p% F- S
  60.       //lwip_close(client);               
    2 v  I8 k: G3 W; d- z
  61.   return HTTP_OK;& J- V+ I: a' q) C2 M) `
  62. }
复制代码

9 |: E) e* _; \5 n! E" I& T' R- r+ D
发送完第一帧图片后,循环发送前面介绍的图片数据格式,就能看到摄像头的实时画面了。
GIF2.gif
8 ?4 M( S" M* U: R1 X1 g
测试源码
【】STM32F429_网络摄像头(网页版)V1.1.rar (1.74 MB, 下载次数: 352)

评分

参与人数 2 ST金币 +13 收起 理由
你若安好_清风徐来 + 5 很给力!
g921002 + 8 很给力!

查看全部评分

1 收藏 19 评论202 发布时间:2019-4-1 17:58

举报

202个回答
昱枫 回答时间:2019-12-19 10:06:22
学习了,' w$ m9 y- M4 l5 D: ~% f/ G
下次可以和楼主的整合一起
7 S2 [' ^2 c# X$ ?6 i. k将视频实时显示在屏幕上,
; q+ z( X2 Y5 @https://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=622494&page=1#pid24732426 L/ i) `& f$ W6 d$ E, G- K  e3 n
4 C, @) [& x7 ]# ]
感谢支持下
1 t# T+ M& X9 L: V- ]
shanji 回答时间:2019-4-3 10:34:11
yklstudent-1794 发表于 2019-4-3 10:16/ Z4 }; i9 I  J1 _2 p& S
楼主请教下,发送数据后就立即关闭连接,之前发送的数据还能发送出去吗? ...
1 |% }# d! _0 ?
关闭连接后发不出去了,需要重新等待客户端的连接。
yklstudent 回答时间:2019-4-3 10:43:01
shanji 发表于 2019-4-3 10:34
0 O2 s' Z4 T* z1 k关闭连接后发不出去了,需要重新等待客户端的连接。

5 t/ d! O. a; p$ ^2 r! ?那为什么send后面要close呢,这样之前的send数据也发不出去啊
海迹天涯 回答时间:2019-4-2 09:30:25
厉害了我的哥
3111272 回答时间:2019-4-2 09:31:44
膜拜大佬
Wature 回答时间:2019-4-2 09:58:24
真的是厉害了我的哥
神奇小芭比 回答时间:2019-4-2 09:59:41
厉害了我的歌
Kevin_G 回答时间:2019-4-2 10:11:11
点赞,超级牛
xiaobai.. 回答时间:2019-4-2 10:41:30
不错
网络孤客 回答时间:2019-4-2 10:54:27
厉害,学习学习!
Bowen 回答时间:2019-4-2 10:54:58
厉害了,学习下
STMWoodData 回答时间:2019-4-2 11:29:19
提示: 作者被禁止或删除 内容自动屏蔽
与我非 回答时间:2019-4-2 11:35:29
厉害厉害
yklstudent 回答时间:2019-4-2 12:32:20
MARK,厉害了我的哥
STMCU-管管 回答时间:2019-4-2 13:00:43
支持支持
七哥 回答时间:2019-4-2 13:04:33
膜拜
老牛洋车 回答时间:2019-4-2 13:20:00
佩服!拜楼主为师。
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版