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

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

[复制链接]
shanji 发布时间:2019-4-1 17:58
本帖最后由 shanji 于 2019-4-27 09:03 编辑 4 d' w; ?" j9 w; h" ?! R: U3 U

/ w% a6 u' v! ^% ~! V3 @* Lhttps://www.stmcu.org.cn/module/forum/thread-609701-1-1.html% ]3 o9 x* X# n! T2 t
距上次分享了个网络摄像头的示例也有一段时间了,用的裸TCP协议,这次来玩玩不同的花样,网页摄像头mjpeg-stream传输,用HTTP协议。网上搜了下,清一色的在Linux下实现的,在单片机上实现的还真没找到,为了玩起来,只能琢磨linux下的代码。
6 v! U5 z, G4 ~) M8 j7 Q        一、先把网页做出来
5 O: y. v" I, i5 `- q      网页端的实现比较简单,用img标签,例:/ ]- H: w3 q+ Z" d; i
<html>
7 z; |1 e, e' D      <head>7 M9 n6 F4 F. m+ S3 v. K
      </head>
0 b6 d- _: m4 `& m- ]0 }1 V      <body>
/ Q; q! R2 ?; r      <img src="http://192.168.1.199:80/?stm32=mjpeg">,此处的ip指的是服务器的ip。  j+ ]9 m. ~( H% t
      </body>6 l# l, \$ V* Z9 ]* L; A, y3 R
</html>
1 i9 `. l# c( a; z5 k0 o      二、 服务端的代码实现2 A' |& F* M; M) f- j
      要在网页上看到不断刷新的图片,服务端需要发送如下的相应包" m9 \; W: @8 r
     HTTP/1.1 200 OK\r\n
! P+ W. V+ V# E0 C1 g4 O& A/ h( o2 k6 {# k2 R4 i5 e/ n
     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. **
    ) p$ l2 ^3 y5 I  F% E; ~% J$ N. I5 |2 M
  2.   * @brief 开始发送流
    8 X& P2 F# D) Z/ o
  3.   * @param  client,count
    $ j" W2 W9 D) C9 Q  [  q7 }5 e
  4.   * @retval None
    ( w, |4 l: @: ]2 d4 H& t% @1 E
  5.   */" e& M5 ~6 }- d* x4 D
  6. HTTP_STA HTTP_Streamer_Start(int client,u8 count)( ~+ D3 @6 @) p- O
  7. {        $ [$ b  c: M3 L3 L5 A" x7 V
  8.     int frame_size=0;, r0 }. F9 @6 Z& Q3 y3 S+ g
  9.    uint16_t haed_len=0;
    # ^' u% |' @' u0 i: b) K9 a7 ?
  10.    sprintf(buffer, "HTTP/1.1 200 OK\r\n"\6 ^8 D4 A9 v, X0 L2 D+ q( ]
  11.    "Connection: Keep-Alive\r\n"\
    " r2 ]3 {, F0 @6 f! s
  12.    "Server: MJPG-Streamer/0.2\r\n"\
    % P6 z! ~( h  s) h/ q, y
  13.    "Cache-Control:no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0\r\n"\0 g+ `9 i, u" p  p, Q9 n, x2 c9 U
  14.    "Pragma:no-cache\r\n"\
    ; x$ x0 N$ ?4 K$ ^
  15.    "Expires:WED, 23 Jan 2019 01:00:00 GMT\r\n"\% n1 W* v+ q) N+ ]! y$ W! `! d* l  h
  16.    "Content-Type: multipart/x-mixed-replace;boundary=openmcu\r\n\r\n"\
    4 \* g, F6 v6 t9 F: O
  17.    "--openmcu\r\n");
    3 b& k4 Q1 E4 V% S, P/ u4 h6 |
  18.                               
    ! q5 U0 y& ~! I' }# i# m: _
  19.     haed_len=strlen(buffer);* i' D; S: M+ v
  20.    //printf("\r\n%s\r\n",buffer);
      M# y6 F  Y. d: Y- P
  21.    if(send(client, buffer,haed_len, 0)==-1)
    + p- F& S4 I( L* x
  22.    {$ H  j3 U4 C: Y$ R9 B6 m
  23.       return HTTP_FAIL;' l$ z5 C8 d/ m# w
  24.    }
    0 [2 N" l/ N& O
  25.   #if USE_CAMERA
    / @* @- @8 M7 F# c
  26.   frame_size=jpeg_data_len();
    * O* [6 H/ B/ z$ S( J6 f
  27.   if(frame_size==0) return HTTP_FAIL;. d: r6 c. v( J% V) V
  28.   #else# m! s- l3 A6 [* N
  29.   if(count==0)
    8 A7 o" b# F4 Z( j
  30.   frame_size=sizeof(cam_data);4 H  }" h, U) F" ?8 k0 W
  31.   else if(count==1)1 U, p: x- B" F# f2 N7 g2 L( z
  32.   frame_size=sizeof(cam_data2);1 s- K# g. r& L7 h2 M
  33.   #endif          8 Z8 Y: q) B: L% X
  34.   haed_len=strlen(buffer);1 W' s" p( P/ \5 @

  35. / `# P/ c6 N0 Q) b  T! Q( o/ W
  36.   sprintf(buffer, "Content-Type: image/jpeg\r\n"\
    % _& f) F$ }: A, y" X* r- n. \
  37.   "Content-Length: %d\r\n\r\n", frame_size);' @+ }9 @3 T2 D  R( @9 q
  38.   printf("\r\n%s\r\n",buffer);
    7 `8 {4 W' I1 Z1 A
  39.   haed_len=strlen(buffer);
    7 v& X' _! ?$ ^
  40.   if(send(client, buffer,haed_len, 0)==-1)
    ! s: i+ ^6 S' K( E
  41.   {
    8 \+ Z& W4 q8 h" M$ c/ K/ o( }
  42.      return HTTP_FAIL;
      D3 k9 L8 {& {  |4 y( o/ a& ]
  43.    }  l7 ]7 c- f! U6 ]$ h$ n
  44.   #if USE_CAMERA
    . g, o! p; K' {1 K2 m* I7 ^
  45.   memcpy(&buffer[haed_len],(char*)ptr,frame_size);) u$ L" w0 t) ~$ y3 W: P. D
  46.   #else
    1 Z1 F. u# [2 z- @4 A
  47.   if(count==0)' n5 Y1 j  i$ g. S% s
  48.   memcpy(&buffer[haed_len],(char*)cam_data,frame_size);
    $ M& N/ O/ B3 ]3 z8 i( f% c7 \
  49.   else if(count==1)
    $ _7 {  O) H; t/ d5 L( S* U9 p
  50.   memcpy(&buffer[haed_len],(char*)cam_data2,frame_size);% x$ j. }, m3 k0 g
  51.   #endif                 
      V0 }1 _1 v$ w5 y3 Q0 [# c
  52.   if(send(client, &buffer[haed_len],frame_size, 0)==-1)- E6 O7 u  m7 P$ P6 }
  53.   {( z* z' k# q4 D; K5 b
  54.      return HTTP_FAIL;
    8 T) P& u$ X: F, `: Z
  55.   }, F) X& B4 E# i9 n% T% [- s$ x
  56.   #if USE_CAMERA- S! ~" ~% V5 e; e$ h
  57.        newframe=0;  
    % M! p1 d: c# h
  58.        cam_start();         
    , S7 H( u# a1 m' |
  59.   #endif
    " t7 e: w( d2 g: ~
  60.       //lwip_close(client);               
    2 ~1 e9 d3 u2 Q6 W: q
  61.   return HTTP_OK;+ \0 k' K! R" ^0 D
  62. }
复制代码

( e. \0 r* n6 p: k! G2 \6 u
发送完第一帧图片后,循环发送前面介绍的图片数据格式,就能看到摄像头的实时画面了。
GIF2.gif
' D* L" Y; c. G" k- \
测试源码
【】STM32F429_网络摄像头(网页版)V1.1.rar (1.74 MB, 下载次数: 398)

评分

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

查看全部评分

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

举报

202个回答
昱枫 回答时间:2019-12-19 10:06:22
学习了,
5 x# b  I- g2 z% a" g, p" _+ Q下次可以和楼主的整合一起
0 ]+ b+ Y1 n8 y  z4 a将视频实时显示在屏幕上,
2 r" Y0 m/ l4 o, ~1 n: Ehttps://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=622494&page=1#pid2473242
& C- B# D8 H! V4 b9 T+ A+ t8 g: Q: w5 c2 d' A5 L" }( ~, x1 W2 ^
感谢支持下8 P1 o- U  ~+ p  |6 g$ ~- k7 l
shanji 回答时间:2019-4-3 10:34:11
yklstudent-1794 发表于 2019-4-3 10:16
9 ^! o5 N! ]! F# ^楼主请教下,发送数据后就立即关闭连接,之前发送的数据还能发送出去吗? ...

( c7 _# a, d' w7 q) G) {关闭连接后发不出去了,需要重新等待客户端的连接。
yklstudent 回答时间:2019-4-3 10:43:01
shanji 发表于 2019-4-3 10:34; q7 {$ t+ N- a$ n" ?9 g! v
关闭连接后发不出去了,需要重新等待客户端的连接。

1 `% C, i# M; }/ H4 P, O2 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 手机版