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

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

[复制链接]
shanji 发布时间:2019-4-1 17:58
本帖最后由 shanji 于 2019-4-27 09:03 编辑 : x, X- w" H5 U6 g0 {6 l

7 t- T8 a! S% ~0 t2 y2 W& S4 Mhttps://www.stmcu.org.cn/module/forum/thread-609701-1-1.html! f! m% {0 W, K$ v9 q
距上次分享了个网络摄像头的示例也有一段时间了,用的裸TCP协议,这次来玩玩不同的花样,网页摄像头mjpeg-stream传输,用HTTP协议。网上搜了下,清一色的在Linux下实现的,在单片机上实现的还真没找到,为了玩起来,只能琢磨linux下的代码。
' F$ v2 \0 q! J/ M' d        一、先把网页做出来% s, U. c! e$ b1 ?. G
      网页端的实现比较简单,用img标签,例:& {6 @0 H; o  W6 ~
<html>
6 p6 ~" Q; S6 Y6 a, B# `* V      <head>
% z  P) Q8 a" c: N- F      </head>  n/ j- J2 h5 S5 L
      <body>, C3 s, {: g' o( A
      <img src="http://192.168.1.199:80/?stm32=mjpeg">,此处的ip指的是服务器的ip。
$ r' b& q  k3 _9 g; ?4 v      </body>
  [1 \3 s, M& l" Q</html>
3 L0 L/ x2 T4 i& n$ N      二、 服务端的代码实现3 ^7 R* Y, [) K
      要在网页上看到不断刷新的图片,服务端需要发送如下的相应包  a: p  U0 o- S, V. p; k
     HTTP/1.1 200 OK\r\n' K; t* v2 o- k9 L

! o; P4 p' {4 ~4 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. **
    1 \+ U0 q4 s9 X( M: d- d1 K
  2.   * @brief 开始发送流
    8 O$ f9 ?* e6 \9 w9 U- C3 c0 G
  3.   * @param  client,count! n. P/ c  ]0 e6 K, l3 A
  4.   * @retval None
    ; \( d9 ~2 X, N3 S* Z0 a( c. M/ O
  5.   */# v7 J. ]$ M0 o% H. [5 @, r
  6. HTTP_STA HTTP_Streamer_Start(int client,u8 count)
    5 g* a3 \0 _) j6 ^- e- ?4 y) y7 ~, Z
  7. {        * r8 N8 B/ x& \/ K6 Z8 q/ P
  8.     int frame_size=0;! g. e) B& ~9 r: e" o9 y
  9.    uint16_t haed_len=0;
    . q2 o8 k6 Q& W; q* \9 x/ N+ y
  10.    sprintf(buffer, "HTTP/1.1 200 OK\r\n"\
    + r( [) Q% m; u, _
  11.    "Connection: Keep-Alive\r\n"\- G- f7 T6 ?: @0 M! w% _/ V# N! G
  12.    "Server: MJPG-Streamer/0.2\r\n"\$ w" B' D5 D9 Z3 U
  13.    "Cache-Control:no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0\r\n"\' `4 e$ W& k* M! e# b- B
  14.    "Pragma:no-cache\r\n"\" q  ~4 Z/ d5 z5 ~0 s& c' k
  15.    "Expires:WED, 23 Jan 2019 01:00:00 GMT\r\n"\& `8 r2 O5 m( L& w
  16.    "Content-Type: multipart/x-mixed-replace;boundary=openmcu\r\n\r\n"\8 {; {4 }3 \  Z7 Q
  17.    "--openmcu\r\n"); ; ?' P/ u  ]9 Z( A8 G! ^9 c7 x/ P
  18.                               
    6 p! F, r9 B* V
  19.     haed_len=strlen(buffer);% G& }) B1 r+ K( Z: c( q6 s
  20.    //printf("\r\n%s\r\n",buffer);
    ' o5 B$ Z/ R8 F: O) z8 r/ C
  21.    if(send(client, buffer,haed_len, 0)==-1)% i5 e( x9 ^; }
  22.    {
    . @& h) X) Y2 [1 w( @8 a
  23.       return HTTP_FAIL;* r4 N. }6 D; M
  24.    }
    # V* l7 i8 V4 m7 |) S
  25.   #if USE_CAMERA
    ) H& b, o/ C% g5 K! m7 d% D
  26.   frame_size=jpeg_data_len();
    % }1 \1 S9 z: ^6 k" D/ k/ K
  27.   if(frame_size==0) return HTTP_FAIL;
    0 \2 S$ @& B: C3 {" ]
  28.   #else
    $ m  n( @5 `+ {  M0 B) t
  29.   if(count==0)
    ' O% s% \& ^0 F4 P8 f) e) b
  30.   frame_size=sizeof(cam_data);
    5 L( X, `- d6 |. `$ l4 ~& M! b
  31.   else if(count==1)' H: B  T9 V1 X1 ~: _" }
  32.   frame_size=sizeof(cam_data2);
    ; W! y, Y7 Z  ?: N( m' C) w5 M3 W2 C
  33.   #endif         
    4 I6 s  c0 W' q! o0 H
  34.   haed_len=strlen(buffer);
    2 L) ]* m; u1 ]5 R9 z1 }
  35. - D6 M- ]* C8 w) u' A6 x9 y
  36.   sprintf(buffer, "Content-Type: image/jpeg\r\n"\% w! d! T6 f, @  ^4 {
  37.   "Content-Length: %d\r\n\r\n", frame_size);
    3 j9 N& ~7 v4 k- ~
  38.   printf("\r\n%s\r\n",buffer);
    + s/ P0 }! N& C, y. Z( i2 k7 [
  39.   haed_len=strlen(buffer);* L9 l, d" O  _* F" k! W9 P2 A3 W
  40.   if(send(client, buffer,haed_len, 0)==-1)
    / m4 s- @' p3 D! V4 r
  41.   {
    ; ^  g, k. f, g5 w) a
  42.      return HTTP_FAIL;
    ; c; S1 h3 Q0 m9 A$ G) Y5 f6 W
  43.    }
    % E6 `1 z' `; I0 N
  44.   #if USE_CAMERA' h- U1 e. ~1 J
  45.   memcpy(&buffer[haed_len],(char*)ptr,frame_size);' ~7 W" y- |4 `
  46.   #else$ s. a) i9 V/ d6 M) r! m5 ?5 w
  47.   if(count==0)8 k( X: `5 r4 y) s) c
  48.   memcpy(&buffer[haed_len],(char*)cam_data,frame_size);7 y/ V5 y8 A9 g! N+ s1 T& O
  49.   else if(count==1)5 v3 ^9 Z$ }7 \5 Q0 j# a
  50.   memcpy(&buffer[haed_len],(char*)cam_data2,frame_size);2 }' i# P5 a- U1 K- c; O
  51.   #endif                 . Y/ m2 j, Q: `# t2 G
  52.   if(send(client, &buffer[haed_len],frame_size, 0)==-1)
    0 r; Q& L4 s4 [0 {4 W" {
  53.   {0 z1 m4 G. r6 L! C
  54.      return HTTP_FAIL;' t& M! E' l7 k+ h% J9 p6 I
  55.   }; t) x7 l4 d% L% q: B
  56.   #if USE_CAMERA
    1 l: q' m' k. X2 T3 w
  57.        newframe=0;  
    - ~9 F3 l7 `; }; y6 _
  58.        cam_start();         
    & S$ B0 N. a) [4 H: @
  59.   #endif
    $ s$ Z9 V6 r- N' s$ h) H
  60.       //lwip_close(client);               
    * c5 q) o0 C, s1 `8 z8 W4 [# k
  61.   return HTTP_OK;6 k  }1 |' a1 b3 U
  62. }
复制代码
7 G! Q( G* D6 b: v
发送完第一帧图片后,循环发送前面介绍的图片数据格式,就能看到摄像头的实时画面了。
GIF2.gif
$ f8 `% [# z) E4 Q8 x+ W; }1 M
测试源码
【】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
学习了," j+ ^6 m4 y0 v
下次可以和楼主的整合一起
4 b" K% f" `# U# M# ?, X$ l! Z将视频实时显示在屏幕上,
; m, |: k+ O2 `" rhttps://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=622494&page=1#pid2473242, y& j9 i6 o0 N. H+ \- Z

3 p' ^9 d$ [) \3 A) m  q* T+ T( d2 p感谢支持下
; b  J# o/ W, @$ _7 I0 m( ?
shanji 回答时间:2019-4-3 10:34:11
yklstudent-1794 发表于 2019-4-3 10:16! _) j) M9 ~* m
楼主请教下,发送数据后就立即关闭连接,之前发送的数据还能发送出去吗? ...

% a7 T; e8 `2 S# h关闭连接后发不出去了,需要重新等待客户端的连接。
yklstudent 回答时间:2019-4-3 10:43:01
shanji 发表于 2019-4-3 10:34+ R7 D- J( A0 ?, k) _( ^- c
关闭连接后发不出去了,需要重新等待客户端的连接。

5 r& g$ T& E6 U% i4 t: C: v/ Q: f那为什么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 手机版