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

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

[复制链接]
shanji 发布时间:2019-4-1 17:58
本帖最后由 shanji 于 2019-4-27 09:03 编辑 , K8 S. Z  j& Q$ Y+ _4 i# C

# _% A2 H9 a( b+ Uhttps://www.stmcu.org.cn/module/forum/thread-609701-1-1.html
5 ?* K, L. ^: t! f距上次分享了个网络摄像头的示例也有一段时间了,用的裸TCP协议,这次来玩玩不同的花样,网页摄像头mjpeg-stream传输,用HTTP协议。网上搜了下,清一色的在Linux下实现的,在单片机上实现的还真没找到,为了玩起来,只能琢磨linux下的代码。
# g5 O5 b* e0 S        一、先把网页做出来! g# z& \5 Y% s2 k
      网页端的实现比较简单,用img标签,例:1 a0 |; h2 C: r- ]1 B, J% O
<html>7 J' Z  ?# E: v) I
      <head>1 T1 i) x" c: `# a+ n! `# f$ r
      </head>
0 A! C3 `  Y" U3 }, i/ U, N8 [      <body>/ e5 |6 Q$ c5 N1 r/ ~
      <img src="http://192.168.1.199:80/?stm32=mjpeg">,此处的ip指的是服务器的ip。: N" a, q% w4 F" j* s8 a
      </body>, X5 E+ {" p; V$ ]0 P
</html>; C  C% W; p  U7 g& g) R
      二、 服务端的代码实现
$ ?9 k# f" X) w" r& b% V
      要在网页上看到不断刷新的图片,服务端需要发送如下的相应包
+ D! Q5 N# Z5 ~* E2 ^6 T     HTTP/1.1 200 OK\r\n
3 H$ t7 I8 J$ D/ l2 L5 K3 A8 I/ b: @! ^& i  }' C2 @# ~( v; G- Q
     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. **
    + m% e& d! _6 \' u( Y) s8 j
  2.   * @brief 开始发送流
    . M' G) _3 C( L* J
  3.   * @param  client,count, w9 H8 s) ^1 p
  4.   * @retval None
    ! |# O$ ]/ @+ T6 D/ q) P$ m- E5 y
  5.   */0 L2 ^6 x8 q# d
  6. HTTP_STA HTTP_Streamer_Start(int client,u8 count)
    ) k; U/ z; s6 q1 K/ S
  7. {        3 T+ g- T8 R3 `. s, M) {2 C
  8.     int frame_size=0;, L1 N% g8 B) v& o: h
  9.    uint16_t haed_len=0;
    $ ^$ g( ?; O2 Q  ^6 k0 P' y
  10.    sprintf(buffer, "HTTP/1.1 200 OK\r\n"\
    1 @' {5 K7 U& I" }: ^5 H  U
  11.    "Connection: Keep-Alive\r\n"\
    % H! D- }) m1 l2 E9 C% U* ?
  12.    "Server: MJPG-Streamer/0.2\r\n"\
    ! X1 L* S1 M2 s" J5 W; z
  13.    "Cache-Control:no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0\r\n"\
    * X" C1 P7 @* L1 @- Q
  14.    "Pragma:no-cache\r\n"\% j% o  M( L# M2 x. C. ?2 C
  15.    "Expires:WED, 23 Jan 2019 01:00:00 GMT\r\n"\
    + e$ i2 L  k+ j9 N# c5 ~- }% H
  16.    "Content-Type: multipart/x-mixed-replace;boundary=openmcu\r\n\r\n"\# Q8 X; S8 Q+ I' U7 t, T& ~; ?" {
  17.    "--openmcu\r\n");
    9 i: h* k% D1 C5 F& u& r& J
  18.                               
    % \9 a: m0 z4 y( A0 ?
  19.     haed_len=strlen(buffer);, @( s. R; _3 S/ }* Y" c7 @/ ^5 O# X
  20.    //printf("\r\n%s\r\n",buffer);) {( A) o" P  m  t+ b; v3 q+ f" O) P
  21.    if(send(client, buffer,haed_len, 0)==-1)6 r4 B1 i4 ~, Y" c
  22.    {7 y* a' F; w# R+ o! Z+ [, ~
  23.       return HTTP_FAIL;3 R  i$ t' h% r* ^3 \
  24.    }' w: ^/ e+ y4 D- X
  25.   #if USE_CAMERA
    6 D3 K; a3 [# w8 Z
  26.   frame_size=jpeg_data_len();
    6 _+ g$ i0 m: K7 L+ i$ [/ C
  27.   if(frame_size==0) return HTTP_FAIL;6 y: s; L# [5 m+ D) e1 n
  28.   #else
    6 f) z) w( {' V" q4 b3 n# d
  29.   if(count==0)4 ?) Q0 r7 U  M+ d7 R2 p
  30.   frame_size=sizeof(cam_data);* J; ^6 T: J/ N: d  W/ o
  31.   else if(count==1)
    * d: R8 _- @" _1 s9 i
  32.   frame_size=sizeof(cam_data2);
    - }3 v2 l) G3 D" v  E8 \3 d' T
  33.   #endif         
    # a6 d( s3 B+ Y) \  R6 E0 d
  34.   haed_len=strlen(buffer);$ {" j, m( a! q- c9 E/ K

  35. 5 R' b# T0 j7 j7 `5 S! c$ w
  36.   sprintf(buffer, "Content-Type: image/jpeg\r\n"\
    # ^) c( e& K( ]4 w- L4 H, R
  37.   "Content-Length: %d\r\n\r\n", frame_size);
    : T1 U2 N- D0 W# i) n2 k1 k
  38.   printf("\r\n%s\r\n",buffer);
    5 u0 @: j5 [1 D3 D
  39.   haed_len=strlen(buffer);. j3 a1 a" K1 R1 v4 ^; h/ h
  40.   if(send(client, buffer,haed_len, 0)==-1)0 }& p$ ~* x/ i
  41.   {
    7 i# m. ]- L# _
  42.      return HTTP_FAIL;
    7 p; b! u3 R- [
  43.    }
    & _* D+ e4 N* {6 X1 D& k$ j$ H
  44.   #if USE_CAMERA
    0 G' y6 w( ~) O. Y& L9 t1 Q
  45.   memcpy(&buffer[haed_len],(char*)ptr,frame_size);
    6 I: f! w; [& |/ X7 a
  46.   #else3 r& G+ L5 [" i4 \6 @* C
  47.   if(count==0)
    , V' _# d6 y+ H% A( x
  48.   memcpy(&buffer[haed_len],(char*)cam_data,frame_size);! l1 d- p7 T# [) e2 L7 C  N) L9 F. t
  49.   else if(count==1)
    ' g# _+ E1 P4 n- ]+ L
  50.   memcpy(&buffer[haed_len],(char*)cam_data2,frame_size);
    . ~, a# |/ C! n4 f  D
  51.   #endif                 + g6 K! T, E5 K* ?4 s1 c6 }
  52.   if(send(client, &buffer[haed_len],frame_size, 0)==-1)
    * ^8 t2 u5 U& q- p  c/ v' ^
  53.   {
    * E- ]/ o" I, H4 h8 E$ a, G6 i
  54.      return HTTP_FAIL;
    / g  v% o3 W9 q! q7 I# L
  55.   }1 |9 _: W% y2 {7 U. o  R
  56.   #if USE_CAMERA
    ( q, t( B! e* n6 Q
  57.        newframe=0;  
    : n+ v( o1 X% y. V1 Q
  58.        cam_start();         
    3 e; b3 }$ p1 m( T7 o+ A9 ~* K  q+ K
  59.   #endif
    6 n1 ?' P" u2 O
  60.       //lwip_close(client);                ) X- p' U: \. @5 I0 `
  61.   return HTTP_OK;
    " w3 q! h( r' \) E/ K: h8 @
  62. }
复制代码
/ z# x$ U/ \4 P7 t
发送完第一帧图片后,循环发送前面介绍的图片数据格式,就能看到摄像头的实时画面了。
GIF2.gif
, Y  `' E8 K2 a2 }
测试源码
【】STM32F429_网络摄像头(网页版)V1.1.rar (1.74 MB, 下载次数: 360)

评分

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

查看全部评分

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

举报

202个回答
昱枫 回答时间:2019-12-19 10:06:22
学习了,
) p% N0 u3 `6 i6 D. }下次可以和楼主的整合一起1 {9 s3 y: Q0 C- _1 l; a1 W
将视频实时显示在屏幕上,# }, _, g7 K! ^/ U
https://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=622494&page=1#pid2473242
2 j! w6 F: N0 B) P* n! b+ L& U! F: W$ Y
感谢支持下
# B7 X# [+ d( S8 y1 P" c; L9 z+ P% v7 a
shanji 回答时间:2019-4-3 10:34:11
yklstudent-1794 发表于 2019-4-3 10:16
. K3 A. }: \  G0 U7 Y. S楼主请教下,发送数据后就立即关闭连接,之前发送的数据还能发送出去吗? ...

- f# I% ?+ k% X2 R3 E3 f2 o" ~# M关闭连接后发不出去了,需要重新等待客户端的连接。
yklstudent 回答时间:2019-4-3 10:43:01
shanji 发表于 2019-4-3 10:34
0 I, }0 \1 [* X( E5 O+ {关闭连接后发不出去了,需要重新等待客户端的连接。
+ t5 P$ O9 @  _( G+ j7 s, 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 手机版