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

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

[复制链接]
shanji 发布时间:2019-4-1 17:58
本帖最后由 shanji 于 2019-4-27 09:03 编辑 8 r8 n+ N! b: X( L* h

1 q) |) P7 z- p/ G' Y# f+ m' Hhttps://www.stmcu.org.cn/module/forum/thread-609701-1-1.html
3 `& O" I* X% F4 [+ ]距上次分享了个网络摄像头的示例也有一段时间了,用的裸TCP协议,这次来玩玩不同的花样,网页摄像头mjpeg-stream传输,用HTTP协议。网上搜了下,清一色的在Linux下实现的,在单片机上实现的还真没找到,为了玩起来,只能琢磨linux下的代码。
& w: G7 J( C3 r" P( i9 ?) q! I7 ~0 _        一、先把网页做出来
, P1 M* z1 W0 w. o- b. @      网页端的实现比较简单,用img标签,例:
' K: \* _, G, N3 q# c$ w8 y<html>  c& p; k  I; A. a- y  o
      <head>
" Y1 g0 V6 I3 w- B$ f" q) m6 @      </head>& }& @, U, J7 N! F
      <body>3 C  ~5 e, f2 J, |5 u+ y" f
      <img src="http://192.168.1.199:80/?stm32=mjpeg">,此处的ip指的是服务器的ip。
4 M: s- B' H9 j. l  a# W      </body>
7 w# T$ q3 T9 ^: J% M</html>0 p2 |+ r( V$ m- [6 O' K. C" G5 s
      二、 服务端的代码实现
, [9 |: S3 ?. ^
      要在网页上看到不断刷新的图片,服务端需要发送如下的相应包1 K) Y6 h$ o5 q3 f
     HTTP/1.1 200 OK\r\n
! a8 _1 B, B" S' x8 h6 ~1 K
) p) K, }7 k, k
     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. **2 ?7 ~0 \9 c; n
  2.   * @brief 开始发送流
    - L) p; {8 u2 ^4 `9 S- e# Y4 F/ ?
  3.   * @param  client,count# _% X3 p6 B- @: ~9 {7 Z, T
  4.   * @retval None
    / p, Z! j5 c: N" {* ^; ?: ]
  5.   */2 o, @  _- j/ ~" e
  6. HTTP_STA HTTP_Streamer_Start(int client,u8 count)7 D" ]7 t+ D# X2 Y6 a
  7. {        4 U, u& s* ]0 h" w2 ~2 `: ]) ]) F# y
  8.     int frame_size=0;
    + q' e4 N3 x+ s  `" q
  9.    uint16_t haed_len=0;
    7 x/ M4 Z- ~. Y- W9 X  k
  10.    sprintf(buffer, "HTTP/1.1 200 OK\r\n"\' e/ J& y  J) z4 Z1 _: f0 M) O
  11.    "Connection: Keep-Alive\r\n"\
    * Z% c% `) A: |" O& f  M
  12.    "Server: MJPG-Streamer/0.2\r\n"\
      m* G! O4 |: n1 p' }
  13.    "Cache-Control:no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0\r\n"\0 T' W* T% x  D+ n
  14.    "Pragma:no-cache\r\n"\8 @) E: o( m0 ~! e1 T1 t
  15.    "Expires:WED, 23 Jan 2019 01:00:00 GMT\r\n"\
    # U2 ^2 t8 R- O7 Q- }6 s2 T  D
  16.    "Content-Type: multipart/x-mixed-replace;boundary=openmcu\r\n\r\n"\
    ; P, X6 l  t/ |" ~; u% s
  17.    "--openmcu\r\n");
    . M8 t; L; h5 s
  18.                               
    2 m& _; @6 L; f2 F' m6 Y
  19.     haed_len=strlen(buffer);% S# v, w1 Z' `* G; c4 f' m) L
  20.    //printf("\r\n%s\r\n",buffer);' g6 W7 D+ h- L! b
  21.    if(send(client, buffer,haed_len, 0)==-1)
    $ f4 z1 w3 v0 k
  22.    {
    % K2 v1 L# L7 G, u3 {: F  i
  23.       return HTTP_FAIL;. {0 G- i; f+ F
  24.    }. S9 b( z6 Z/ ~* w& K/ R; p( }& z. F. h2 c
  25.   #if USE_CAMERA
    & n7 S. `- X  V0 C
  26.   frame_size=jpeg_data_len();
    1 H. t. P5 G3 m- C- v! k$ T
  27.   if(frame_size==0) return HTTP_FAIL;* ~0 j- t# m+ S- S# l$ _
  28.   #else
    " X$ R- g1 Q5 L  c' L  }, T4 n0 N$ i
  29.   if(count==0)" m( l3 m1 C, c) h
  30.   frame_size=sizeof(cam_data);
    / d2 Y8 [; G( ^8 o
  31.   else if(count==1)5 r3 S/ b0 t8 A  O8 ]
  32.   frame_size=sizeof(cam_data2);. k, `; Z' S6 L. u  Q4 `; U
  33.   #endif          6 H/ L  u* q- x$ U4 ~5 \
  34.   haed_len=strlen(buffer);
    % P$ z+ P/ ~* p( S/ x5 H

  35. " A" M& a4 R' C% t1 z
  36.   sprintf(buffer, "Content-Type: image/jpeg\r\n"\" d' Z: Z  H6 k
  37.   "Content-Length: %d\r\n\r\n", frame_size);, g6 z+ t0 J5 X
  38.   printf("\r\n%s\r\n",buffer);
    2 u' n- A! t/ ?( L  h# H. d6 J4 r
  39.   haed_len=strlen(buffer);# `3 J* y5 {  Q  G: ^5 [7 t
  40.   if(send(client, buffer,haed_len, 0)==-1)  L* M/ F/ n/ ?+ j3 W9 F8 A
  41.   {8 W* d& j. [! ]% B4 ~
  42.      return HTTP_FAIL;3 P) h* [6 y5 [  d* S) P/ N9 P+ t
  43.    }
    5 |' O, {. h% t7 C' r1 z0 x* ?+ k" n: V
  44.   #if USE_CAMERA
    ! b  X% {$ ?4 M2 H
  45.   memcpy(&buffer[haed_len],(char*)ptr,frame_size);
    " W& ?5 N, J3 s
  46.   #else
    , {5 x9 \2 C  j6 j* c! T0 e
  47.   if(count==0)
    4 O/ k3 ]5 Z, g: o  _% T$ N: ?
  48.   memcpy(&buffer[haed_len],(char*)cam_data,frame_size);
    6 O9 J8 s! r+ i- v) `! l
  49.   else if(count==1)
    ( ~5 r, O3 l! q; \- [5 L% F
  50.   memcpy(&buffer[haed_len],(char*)cam_data2,frame_size);/ Y5 |: ?, p9 p9 {' p
  51.   #endif                 
    7 i% K' S1 Z9 \* ?8 j3 J$ F0 B# n
  52.   if(send(client, &buffer[haed_len],frame_size, 0)==-1)
    - u, H) w; d4 N2 l+ U2 ~) u
  53.   {
    * S$ l6 h" `0 V( h8 V# W0 a
  54.      return HTTP_FAIL;
    + H7 {) h( ]- T2 |* \
  55.   }
    ' [/ I' y, z. B
  56.   #if USE_CAMERA
    / X7 }7 R2 h$ Z  T: U
  57.        newframe=0;  
    ; p6 T/ b( N+ }+ f' G4 k
  58.        cam_start();         
    " e9 E- a' x( U, Q' q( H
  59.   #endif( O+ V" A5 i+ c7 r5 l  A: J1 s
  60.       //lwip_close(client);                / d, O# |! N" @- D6 r+ m
  61.   return HTTP_OK;
    3 N2 T! n0 o1 R! D. w- n7 c5 \0 N
  62. }
复制代码
( @; H" ~  K. ~: J8 _+ W7 [
发送完第一帧图片后,循环发送前面介绍的图片数据格式,就能看到摄像头的实时画面了。
GIF2.gif

$ c: e/ P! O! o! T) ?% @; {  W$ l
测试源码
【】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
学习了,
' l* e5 W3 Q* M$ a下次可以和楼主的整合一起7 t* s( ]$ w1 c. s
将视频实时显示在屏幕上,
; u5 f# C, H8 l( v0 Mhttps://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=622494&page=1#pid2473242
+ T3 S  p$ f: j0 D. f( X. y5 w1 V" {' e$ I( `- |
感谢支持下; ]9 i- g- E" `) W: {/ j
shanji 回答时间:2019-4-3 10:34:11
yklstudent-1794 发表于 2019-4-3 10:16
8 m3 E( s: M) e( y8 @6 E# q楼主请教下,发送数据后就立即关闭连接,之前发送的数据还能发送出去吗? ...

( X( i! I2 d4 A3 L  J关闭连接后发不出去了,需要重新等待客户端的连接。
yklstudent 回答时间:2019-4-3 10:43:01
shanji 发表于 2019-4-3 10:34
' C  k. P+ y) c/ v8 Q" g关闭连接后发不出去了,需要重新等待客户端的连接。

0 c- M! o+ w7 i( U% Q1 T那为什么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 手机版