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

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

[复制链接]
shanji 发布时间:2019-4-1 17:58
本帖最后由 shanji 于 2019-4-27 09:03 编辑 % i' \( u$ Y6 j; S. O  L1 s9 N

5 t( _) m& I; R. g  Hhttps://www.stmcu.org.cn/module/forum/thread-609701-1-1.html% _; t3 ~+ }4 P
距上次分享了个网络摄像头的示例也有一段时间了,用的裸TCP协议,这次来玩玩不同的花样,网页摄像头mjpeg-stream传输,用HTTP协议。网上搜了下,清一色的在Linux下实现的,在单片机上实现的还真没找到,为了玩起来,只能琢磨linux下的代码。
& ]) o/ A& Q( ~        一、先把网页做出来
* P. u/ i  K& `- F6 R% Q( |      网页端的实现比较简单,用img标签,例:0 ?" Y$ x: Q6 ~
<html>) Z6 L) }( O( V
      <head>
  ^9 V; C! g# x1 |3 j      </head>
2 B) _9 @5 R4 h+ L  _      <body>
9 F: s9 A5 ?' p: S8 {7 S- s      <img src="http://192.168.1.199:80/?stm32=mjpeg">,此处的ip指的是服务器的ip。
; W' m9 K. N* y% m# Z2 f      </body>/ m: d( o( C+ J* m3 D
</html>  u% L" y% s+ _8 j' l4 t
      二、 服务端的代码实现
' W7 F# V* n0 Q# \# l7 f, U8 a
      要在网页上看到不断刷新的图片,服务端需要发送如下的相应包( p! O7 d  q. f: i! A8 Q) p
     HTTP/1.1 200 OK\r\n
3 P* G! d( e& w. Z4 t, \' V0 d$ z3 U7 B5 b# a/ C
     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. **
    # [) D' c; U1 F  b7 C. Y8 m# P/ I
  2.   * @brief 开始发送流
    . i- p" n* j/ J( P, i# _
  3.   * @param  client,count
    8 y( o+ w# W2 ~% `* m, \
  4.   * @retval None( {( }# w5 y) V2 r6 D$ S
  5.   */
    * q( k( l. w5 n6 {4 a
  6. HTTP_STA HTTP_Streamer_Start(int client,u8 count)
    . v  E: V* I7 h+ z( R
  7. {        
    ) l/ J: x' l1 S4 n- j, O+ R
  8.     int frame_size=0;) P1 g% O* A9 i1 ~0 f" Z
  9.    uint16_t haed_len=0;
    : l- H+ a2 H" b2 n
  10.    sprintf(buffer, "HTTP/1.1 200 OK\r\n"\: b9 U4 {# k+ d8 v
  11.    "Connection: Keep-Alive\r\n"\$ Z  u% v; N) v8 B! V8 P" A/ }
  12.    "Server: MJPG-Streamer/0.2\r\n"\
    . V0 D. v, b* n+ |
  13.    "Cache-Control:no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0\r\n"\
    $ n- V5 Z0 y4 q. U
  14.    "Pragma:no-cache\r\n"\0 o* p8 a$ k# y) y
  15.    "Expires:WED, 23 Jan 2019 01:00:00 GMT\r\n"\* \- ?! y. i) z4 a3 w* G
  16.    "Content-Type: multipart/x-mixed-replace;boundary=openmcu\r\n\r\n"\0 T; ^9 i& _- S. |) `( X1 I+ T
  17.    "--openmcu\r\n"); " g, Z- n0 c- c/ o- K1 U( K9 o
  18.                               
    6 ?. A# c. V) w
  19.     haed_len=strlen(buffer);
    5 D1 e, x% Q& }+ u9 I3 J* j/ c
  20.    //printf("\r\n%s\r\n",buffer);; d, \# x7 b. ]+ ]  f- u3 h
  21.    if(send(client, buffer,haed_len, 0)==-1)5 H" i. c, n5 x; A, P0 u8 C
  22.    {
    & j* [+ D. r8 e' i$ a; h7 v$ \
  23.       return HTTP_FAIL;
    1 x" E! s! y+ T
  24.    }
    ; K' Q: D: u: S- q) x2 s
  25.   #if USE_CAMERA
    & H4 t: Y8 Y: }: L+ O# g
  26.   frame_size=jpeg_data_len();
    ; `8 |* Q. G) ^% G0 w
  27.   if(frame_size==0) return HTTP_FAIL;. P! `" u$ n' ^5 i. V
  28.   #else
    ( u! e  k- n/ Q3 g' y
  29.   if(count==0)6 R; t* k4 |4 b. L6 O( @0 m
  30.   frame_size=sizeof(cam_data);
    - O3 I5 @( [6 r) k0 G" \, Z1 N
  31.   else if(count==1)
    % O5 z# J+ G4 h
  32.   frame_size=sizeof(cam_data2);9 ~. B, [/ {$ l# }
  33.   #endif          - H2 y8 E. p3 Y3 E
  34.   haed_len=strlen(buffer);
    3 r# z- P2 {" d/ t( j

  35. - M8 d3 y/ T& |1 M8 ~  w
  36.   sprintf(buffer, "Content-Type: image/jpeg\r\n"\1 S. I3 f  U9 l; m0 l
  37.   "Content-Length: %d\r\n\r\n", frame_size);$ v5 R% M8 h+ k9 K
  38.   printf("\r\n%s\r\n",buffer);
    ( w; g1 l# o9 o( ~" N6 X0 t2 x
  39.   haed_len=strlen(buffer);( w/ P1 z% f! I6 g; ?6 a' \5 e
  40.   if(send(client, buffer,haed_len, 0)==-1): f) g! F8 U( s
  41.   {
    $ v! J; m+ H+ ^' t
  42.      return HTTP_FAIL;5 n% j9 O& P( Q+ O
  43.    }
    1 ]3 g" @2 }+ Y7 n- N2 S( e" h
  44.   #if USE_CAMERA+ f' P5 K; j6 |8 P2 v$ `
  45.   memcpy(&buffer[haed_len],(char*)ptr,frame_size);
    / z0 ]% u* d. C
  46.   #else" J) @% M2 x- }( n5 t
  47.   if(count==0)3 l% u' B8 b& @9 Q' T
  48.   memcpy(&buffer[haed_len],(char*)cam_data,frame_size);! a/ x& W& O, u( J4 F  q# I
  49.   else if(count==1)
    ( y0 p* N: u* T7 ?, X1 B5 A
  50.   memcpy(&buffer[haed_len],(char*)cam_data2,frame_size);
    7 p! c. U) s1 u: t6 D
  51.   #endif                 / c3 H" x/ ?  c& G, p/ o& E
  52.   if(send(client, &buffer[haed_len],frame_size, 0)==-1)! G5 r4 n. N, k
  53.   {
    2 j3 ]$ R) k3 n  ^1 [# N& g. R& s
  54.      return HTTP_FAIL;
    / k: h  ~; C4 C/ z0 g- ~
  55.   }
    . g/ I; v( O' K) Z0 ~' r9 Y$ m: Y
  56.   #if USE_CAMERA
    * K4 A2 j& F; s" T% K9 j
  57.        newframe=0;  5 X+ V; v4 [/ C. j% X. Y4 b
  58.        cam_start();         
    , y- ^" k6 a' z. F6 g8 D
  59.   #endif- _# r: n( y. e2 T0 e" [3 T) D
  60.       //lwip_close(client);                ) ?. P6 n: Z; `1 s
  61.   return HTTP_OK;
    + s: _  v4 P& f
  62. }
复制代码

, |/ d* G* d% R
发送完第一帧图片后,循环发送前面介绍的图片数据格式,就能看到摄像头的实时画面了。
GIF2.gif
# `/ M3 }- v6 e
测试源码
【】STM32F429_网络摄像头(网页版)V1.1.rar (1.74 MB, 下载次数: 403)

评分

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

查看全部评分

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

举报

202个回答
昱枫 回答时间:2019-12-19 10:06:22
学习了,
$ n9 W  p" f0 ^, ~2 ^- I' J下次可以和楼主的整合一起$ [! q$ Z" M- H% w3 b# C
将视频实时显示在屏幕上,' _+ U6 m; c. `
https://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=622494&page=1#pid2473242
# n; u, @5 [% O& @# Z
0 H  ^' t! r- \& H感谢支持下
3 M; i, f" R$ i2 _' u, B
shanji 回答时间:2019-4-3 10:34:11
yklstudent-1794 发表于 2019-4-3 10:16% m* r3 ]/ B; O4 ]; R( g8 z
楼主请教下,发送数据后就立即关闭连接,之前发送的数据还能发送出去吗? ...
) c* F( k4 R* r( ~* z% Y
关闭连接后发不出去了,需要重新等待客户端的连接。
yklstudent 回答时间:2019-4-3 10:43:01
shanji 发表于 2019-4-3 10:34
, {6 N/ ]$ f) n) {' P9 H关闭连接后发不出去了,需要重新等待客户端的连接。

; }" ?: E- D  n$ Q& _8 z  i; @那为什么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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版