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

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

[复制链接]
shanji 发布时间:2019-4-1 17:58
本帖最后由 shanji 于 2019-4-27 09:03 编辑 " Z$ R# Z: @' F* J2 G9 H" `5 P
. q" |+ P6 g! O8 j2 X
https://www.stmcu.org.cn/module/forum/thread-609701-1-1.html
' S3 O4 G9 m/ ]4 l4 _距上次分享了个网络摄像头的示例也有一段时间了,用的裸TCP协议,这次来玩玩不同的花样,网页摄像头mjpeg-stream传输,用HTTP协议。网上搜了下,清一色的在Linux下实现的,在单片机上实现的还真没找到,为了玩起来,只能琢磨linux下的代码。, Z% O  O* x6 u6 L% f3 j: Y1 ]
        一、先把网页做出来
  V( \! E. l# a* F) f      网页端的实现比较简单,用img标签,例:
+ R& C3 [9 p& H, X$ B2 A<html>
" D6 m/ A, A9 R- c      <head>0 |5 U2 C/ o  L% C4 |9 N8 z
      </head>3 v' O: X3 T3 f' U
      <body>5 r! C& w# k# f  x7 ]# u
      <img src="http://192.168.1.199:80/?stm32=mjpeg">,此处的ip指的是服务器的ip。
( Y& J: F% `# u      </body>( Q# B1 A7 C3 [3 i5 z3 O
</html>1 M( s8 g  Z3 W/ v0 X* p
      二、 服务端的代码实现
0 [/ r4 k( w: k5 e1 f
      要在网页上看到不断刷新的图片,服务端需要发送如下的相应包
  e9 l& k* ~& g1 Y: }     HTTP/1.1 200 OK\r\n
" w7 m4 w2 ?% [; l% f' k0 g
/ g- t4 Z' ?' ?
     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. **7 r. f8 m' d: a. v: c# A# H. U
  2.   * @brief 开始发送流
    6 D3 D& m- i4 Y, v
  3.   * @param  client,count' ]# H( |& W+ C. R4 B  f5 ?
  4.   * @retval None
    . l* O* N9 N' e
  5.   */
    ' ~$ O! X/ D) U/ H2 ^4 _
  6. HTTP_STA HTTP_Streamer_Start(int client,u8 count)
    , `7 B3 A' V& Y9 H  g: P8 b
  7. {        
    $ h9 T) L/ y; N, x. O
  8.     int frame_size=0;
    8 r/ y. y6 ?$ [. _
  9.    uint16_t haed_len=0;
    / a( F5 |7 _/ b9 P# L
  10.    sprintf(buffer, "HTTP/1.1 200 OK\r\n"\
    ( F; Y' l+ L# r% x
  11.    "Connection: Keep-Alive\r\n"\3 l$ E, q8 w8 ?! K
  12.    "Server: MJPG-Streamer/0.2\r\n"\
    - z) r' }7 {7 A- F- k. u, L
  13.    "Cache-Control:no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0\r\n"\8 P5 S0 m8 u6 E, J
  14.    "Pragma:no-cache\r\n"\
    ! E4 a3 N( g$ Z: x
  15.    "Expires:WED, 23 Jan 2019 01:00:00 GMT\r\n"\: s+ b* a0 w: G$ {
  16.    "Content-Type: multipart/x-mixed-replace;boundary=openmcu\r\n\r\n"\
    ( V- w! O" S" n
  17.    "--openmcu\r\n");
    " |2 @" u1 _  {# @2 t: b, A; `
  18.                               - o+ O% u. c: T3 U* F8 }) D
  19.     haed_len=strlen(buffer);  N' e9 R& j0 s% c
  20.    //printf("\r\n%s\r\n",buffer);
    5 A7 x1 a% @4 T) \5 f, M0 S( |
  21.    if(send(client, buffer,haed_len, 0)==-1)% {# Z: r! r7 ]* c' ?* F& x
  22.    {
    . C# h, Y) z6 R
  23.       return HTTP_FAIL;
    + c. Y; m8 `. M2 l! c. M/ ~0 ]
  24.    }
      [3 ^5 @: T! J. ~! v
  25.   #if USE_CAMERA
    ) y& @+ F! u. I- k
  26.   frame_size=jpeg_data_len();
    * k# C, E( J" ?1 p  X' r
  27.   if(frame_size==0) return HTTP_FAIL;
    1 X8 l( B6 L6 H
  28.   #else' h0 z+ Q! p/ t
  29.   if(count==0)8 S0 C# h  D9 t" `4 X2 _' Y
  30.   frame_size=sizeof(cam_data);
    : b4 ~! b  f1 [( _4 N$ l+ {( G! \
  31.   else if(count==1)
    . d: I. k) a, s0 f9 n* M3 j% `8 W
  32.   frame_size=sizeof(cam_data2);
    : f, R4 Q4 b" L7 v1 b; r$ M9 P
  33.   #endif          # y, L; O0 q7 V
  34.   haed_len=strlen(buffer);
    * b5 c( b: D2 N& y; @1 \! z
  35. 8 X$ Z; g. }  u
  36.   sprintf(buffer, "Content-Type: image/jpeg\r\n"\+ B: }) Z: d* R% f1 `! y, T
  37.   "Content-Length: %d\r\n\r\n", frame_size);0 q* k4 X  H0 o3 O& Y# ?
  38.   printf("\r\n%s\r\n",buffer);5 g1 I  f( j# }+ L3 [; v. R
  39.   haed_len=strlen(buffer);
    2 V$ U( I6 b& T. v1 q9 d& S
  40.   if(send(client, buffer,haed_len, 0)==-1)
    4 ^7 B( }4 V" I* Q
  41.   {
    ! `0 Y3 N3 p! ~1 l& U9 ]8 h
  42.      return HTTP_FAIL;
    % _$ [$ z' [4 k
  43.    }
    ; Q# f) x, p/ {! \  g
  44.   #if USE_CAMERA' r- G& U9 P' w0 a% e
  45.   memcpy(&buffer[haed_len],(char*)ptr,frame_size);
    + x  |/ a  n. s0 Z; t$ P" {. W
  46.   #else* w8 {% c' S- x; H$ D
  47.   if(count==0)5 i) R+ m2 L5 ~0 Y6 P' b
  48.   memcpy(&buffer[haed_len],(char*)cam_data,frame_size);7 T9 S/ D: K6 h4 D1 f# L
  49.   else if(count==1)
    " \# J0 z9 o% e! \; {' d; H3 b5 N
  50.   memcpy(&buffer[haed_len],(char*)cam_data2,frame_size);9 r, t  r* ^4 Z
  51.   #endif                 
    9 i4 q% k8 j$ V6 f
  52.   if(send(client, &buffer[haed_len],frame_size, 0)==-1)
    9 v! z' O5 e# L( j
  53.   {
    3 f! W( F3 t; t1 q8 v( t$ C
  54.      return HTTP_FAIL;
    3 X* z/ `) g1 h9 @* l9 z
  55.   }
    + A$ j- q3 F: M, u& L2 I3 Y
  56.   #if USE_CAMERA! p" m& H9 I, t& S1 ]' j" _! e: L
  57.        newframe=0;  0 {( V5 k0 ^0 L4 n: N
  58.        cam_start();         
    , b- [: @6 r- k& H" o; t
  59.   #endif7 o+ P3 Z$ D( _/ S5 a
  60.       //lwip_close(client);               
    7 n3 l  B0 U+ x- z
  61.   return HTTP_OK;
    , G+ l% t7 _' l' ~$ e; V7 y
  62. }
复制代码

  A  e, e2 u6 F
发送完第一帧图片后,循环发送前面介绍的图片数据格式,就能看到摄像头的实时画面了。
GIF2.gif
& j: H( c7 s0 y; K) b' Z
测试源码
【】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
学习了,6 k$ O. [% z" {5 x9 ]' @; R- E
下次可以和楼主的整合一起
' V6 \. f8 I5 B/ Q8 S5 p将视频实时显示在屏幕上,
& C) y- O7 X; a, x! d5 _5 G3 vhttps://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=622494&page=1#pid2473242
2 ?9 `4 B% D5 `1 T
: W: h. e% l2 E3 A$ I, _' b# D感谢支持下( C: o7 ^9 z. f5 e6 J
shanji 回答时间:2019-4-3 10:34:11
yklstudent-1794 发表于 2019-4-3 10:16; \3 ]5 L9 _8 y$ E
楼主请教下,发送数据后就立即关闭连接,之前发送的数据还能发送出去吗? ...
) W, i! Z: |7 R: k3 [
关闭连接后发不出去了,需要重新等待客户端的连接。
yklstudent 回答时间:2019-4-3 10:43:01
shanji 发表于 2019-4-3 10:34
' _8 M7 L4 H4 Q% \% K+ z关闭连接后发不出去了,需要重新等待客户端的连接。

4 \. `# b+ c: 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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版