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

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

[复制链接]
shanji 发布时间:2019-4-1 17:58
本帖最后由 shanji 于 2019-4-27 09:03 编辑 # `5 v$ O6 l3 M0 Z

+ F; w- O2 ~1 W  Z7 _! ^$ ^https://www.stmcu.org.cn/module/forum/thread-609701-1-1.html
# j" f( ^: [* X( E) D1 j( L3 L, x距上次分享了个网络摄像头的示例也有一段时间了,用的裸TCP协议,这次来玩玩不同的花样,网页摄像头mjpeg-stream传输,用HTTP协议。网上搜了下,清一色的在Linux下实现的,在单片机上实现的还真没找到,为了玩起来,只能琢磨linux下的代码。& U1 n  a5 z  y1 u, L! ^
        一、先把网页做出来# m0 ]+ ~+ y2 E5 J2 h
      网页端的实现比较简单,用img标签,例:/ ]7 `! D2 m3 I+ W) k9 l2 G
<html>
' [* v, v! d0 P8 Y5 I+ l      <head>% I4 {+ y0 o2 C0 p
      </head>
! F. U$ e. v# ]9 Z- ]/ C. t      <body>
9 S; j9 v/ V: c) G2 t8 Q' W      <img src="http://192.168.1.199:80/?stm32=mjpeg">,此处的ip指的是服务器的ip。
) g5 C& G' T; W# X4 D; A0 Z      </body>
! V. K0 N3 E, v& ~- \</html>; y9 p& v& Y! [, e6 P) Z- s8 b4 \
      二、 服务端的代码实现! W$ {( c0 \8 r9 m# v% \! G# b
      要在网页上看到不断刷新的图片,服务端需要发送如下的相应包
. b* w7 Z: S/ F     HTTP/1.1 200 OK\r\n8 y8 o7 z1 v$ q& l+ b- G6 J0 o
# W7 g- C6 \8 w' _6 d+ L/ \8 L
     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. **
    5 B# x, p, Y) Z% k% g& }
  2.   * @brief 开始发送流
    3 E& T. P" m- W) U0 s! p- a4 Y
  3.   * @param  client,count
    2 N3 E" J4 u8 L. S/ Q
  4.   * @retval None( T) J+ ]2 ~) }4 D, X
  5.   */8 E2 d% V6 s" v, z% W. {* k
  6. HTTP_STA HTTP_Streamer_Start(int client,u8 count)
    ' c2 z! Y* q; l& e6 `
  7. {        
    * [6 C  e7 g. {% Z; @5 \
  8.     int frame_size=0;) V4 E: l% J* o# v" g  b! s1 W3 P
  9.    uint16_t haed_len=0;
    6 x9 e+ p5 r: m0 i4 v$ g  p% W
  10.    sprintf(buffer, "HTTP/1.1 200 OK\r\n"\6 F) U  Y. x2 J3 f  \
  11.    "Connection: Keep-Alive\r\n"\
    2 A; L0 d& V$ K: z$ C2 M6 a3 R
  12.    "Server: MJPG-Streamer/0.2\r\n"\: }( O, W3 Q6 f% m
  13.    "Cache-Control:no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0\r\n"\
    1 U  j9 r% ]3 V# R. q! `
  14.    "Pragma:no-cache\r\n"\
    1 I* Y% i) y7 ~4 ?/ u
  15.    "Expires:WED, 23 Jan 2019 01:00:00 GMT\r\n"\
    , _9 P+ C% e" y
  16.    "Content-Type: multipart/x-mixed-replace;boundary=openmcu\r\n\r\n"\
    4 Q3 e, n) `2 N: t% m
  17.    "--openmcu\r\n");
    5 z2 \' o& H! ~# W! O  p9 y) S
  18.                               ) }& f) P9 T5 o- v3 \9 [+ k
  19.     haed_len=strlen(buffer);9 G+ E9 X1 L# Y7 I
  20.    //printf("\r\n%s\r\n",buffer);
    8 S+ O, T4 Q0 A
  21.    if(send(client, buffer,haed_len, 0)==-1)! U4 z- X$ N0 ?# X: _
  22.    {+ S- W( ^# J- h4 W" d) Q5 a
  23.       return HTTP_FAIL;2 F# L6 p% s3 G! `
  24.    }; k$ @+ Z+ `' x& l2 t* `, u
  25.   #if USE_CAMERA
    ; \0 j- h6 ?$ x% |2 T. B. a+ G
  26.   frame_size=jpeg_data_len();
    # i) h% r: ]! j6 H" L
  27.   if(frame_size==0) return HTTP_FAIL;" A: H8 \9 r( j' A( l/ d
  28.   #else5 J5 D7 j' N; b8 Y' t
  29.   if(count==0)
    2 D9 h7 c/ D5 T3 F
  30.   frame_size=sizeof(cam_data);
    0 j4 U$ T" K$ `1 L
  31.   else if(count==1)
    ) [; S7 Z5 h  p7 ?; q! ], P- R  @
  32.   frame_size=sizeof(cam_data2);
    " R8 X$ R. f" `+ T- w- f5 r# c# K3 t
  33.   #endif          9 y9 u* F9 K9 j7 c1 n, l) C  R
  34.   haed_len=strlen(buffer);$ ]0 w4 h# K; ?" _$ o/ ^3 R
  35. / Q1 S# s! M' |
  36.   sprintf(buffer, "Content-Type: image/jpeg\r\n"\
    : d( ^0 _6 n/ x
  37.   "Content-Length: %d\r\n\r\n", frame_size);) o8 |  }* s3 V9 ^8 g, l( K
  38.   printf("\r\n%s\r\n",buffer);
    ( h: U- H, Q4 q4 ]4 f' @' B
  39.   haed_len=strlen(buffer);
    9 Z" }7 K2 z& E* x1 j/ m
  40.   if(send(client, buffer,haed_len, 0)==-1)3 B* T: A. x9 i8 U' X/ A6 b9 W& n
  41.   {
    9 Z8 }$ D% f' e  t& j
  42.      return HTTP_FAIL;
    ; B4 ~6 o5 r2 ^
  43.    }  o5 x# H: [  y
  44.   #if USE_CAMERA% U% V8 t7 m# v+ p# L
  45.   memcpy(&buffer[haed_len],(char*)ptr,frame_size);
    & c- a  o: a! D. L: t! X
  46.   #else
    7 L* Y9 y* n9 l
  47.   if(count==0)
      B+ T( a( n; e5 L0 g- c: _
  48.   memcpy(&buffer[haed_len],(char*)cam_data,frame_size);% w  b7 i9 j0 H; F7 q3 S
  49.   else if(count==1)# |6 l& j# l1 I7 b7 z; E- H
  50.   memcpy(&buffer[haed_len],(char*)cam_data2,frame_size);1 l; r; V8 T, ]2 R1 R; ?
  51.   #endif                 
    9 P% ~$ L9 N$ U0 X) n2 T2 l! N
  52.   if(send(client, &buffer[haed_len],frame_size, 0)==-1)6 H* {0 ~9 D0 W, t9 Z
  53.   {
    , D3 M5 R) l% Q. I9 f/ [  ]% S5 ~
  54.      return HTTP_FAIL;
    / y- H6 D. J9 A' ]) ~. v
  55.   }
    - K) T2 K( g) |, b6 \; z
  56.   #if USE_CAMERA
    ! H( h; T: k. k2 C; F" \6 }
  57.        newframe=0;  
    5 T0 p. i  a& ]' h  r2 z
  58.        cam_start();         
    ; ]8 @0 C! x$ c0 y3 u0 h: ^& C
  59.   #endif( v! j% i4 ]. }9 l, e
  60.       //lwip_close(client);                ( {2 ^! e$ i: W0 Q1 Z: z1 F
  61.   return HTTP_OK;
    ) i: z& C, l" F) t4 j3 m
  62. }
复制代码

' T) I! K' |- l1 r
发送完第一帧图片后,循环发送前面介绍的图片数据格式,就能看到摄像头的实时画面了。
GIF2.gif

' t. z. n9 q3 N) j; F# b- i* v
测试源码
【】STM32F429_网络摄像头(网页版)V1.1.rar (1.74 MB, 下载次数: 354)

评分

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

查看全部评分

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

举报

202个回答
昱枫 回答时间:2019-12-19 10:06:22
学习了,' [4 M# G: o5 G& f% K! f
下次可以和楼主的整合一起
& u; I. ]! L- \将视频实时显示在屏幕上,+ e7 d  \& h3 z% ]' [- O2 p
https://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=622494&page=1#pid2473242
* p. F) `& [0 _  s
$ O/ e& z9 ^0 B. j8 b8 E5 e感谢支持下2 }9 m  M5 x% v. Q* q% ]
shanji 回答时间:2019-4-3 10:34:11
yklstudent-1794 发表于 2019-4-3 10:16$ r- v, |% [# m0 w. j; t' h( C
楼主请教下,发送数据后就立即关闭连接,之前发送的数据还能发送出去吗? ...
) o; Z% q- @9 j' h+ u0 W- B2 W% g
关闭连接后发不出去了,需要重新等待客户端的连接。
yklstudent 回答时间:2019-4-3 10:43:01
shanji 发表于 2019-4-3 10:34
4 \  g# m7 @* H! y8 B关闭连接后发不出去了,需要重新等待客户端的连接。
7 n! M7 |6 ]9 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 手机版