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

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

[复制链接]
shanji 发布时间:2019-4-1 17:58
本帖最后由 shanji 于 2019-4-27 09:03 编辑 4 q/ {! P# o" G5 z- d/ q- q+ p8 R
+ P. k( o( i: [2 A4 e9 D
https://www.stmcu.org.cn/module/forum/thread-609701-1-1.html
, T* e3 w3 Z% Z( T: A" C3 Q距上次分享了个网络摄像头的示例也有一段时间了,用的裸TCP协议,这次来玩玩不同的花样,网页摄像头mjpeg-stream传输,用HTTP协议。网上搜了下,清一色的在Linux下实现的,在单片机上实现的还真没找到,为了玩起来,只能琢磨linux下的代码。2 E* J6 N, C4 C& ]0 U: s
        一、先把网页做出来$ N3 Z; u, L( F- Q- N# h: `
      网页端的实现比较简单,用img标签,例:
6 G( W+ d/ e7 o- r- }9 [, y<html>
  o% Q1 f+ ^- Y0 Z      <head>
4 k: W' j8 W# m      </head>7 R3 V3 }6 {) @9 q" n* u7 j, |
      <body>$ c  ^$ H& p: i
      <img src="http://192.168.1.199:80/?stm32=mjpeg">,此处的ip指的是服务器的ip。
3 @4 s+ k) B; f0 c/ d      </body>
; v4 l; j5 o: |& z! q</html>
4 K& w* [8 C# n      二、 服务端的代码实现
' B4 \% F- {8 r5 o% i
      要在网页上看到不断刷新的图片,服务端需要发送如下的相应包% Z& Z- l7 A3 P3 d7 ^9 k6 @' {
     HTTP/1.1 200 OK\r\n
3 W$ p* ]9 H* C, v, U, z+ W( P; i4 b9 n; d: c3 C6 k) f
     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. *** ^8 r, _" T$ `$ Q
  2.   * @brief 开始发送流
    6 k7 q9 O. P9 O# o/ C$ }
  3.   * @param  client,count! c3 u& c. K0 d3 ~$ I% n/ M; b
  4.   * @retval None8 K7 t3 p. }3 l$ [* O' S
  5.   */
    % H, l7 k# y3 D1 M# B
  6. HTTP_STA HTTP_Streamer_Start(int client,u8 count)& Q4 b- k6 c1 K. ~
  7. {          N, S6 E/ v% C3 [
  8.     int frame_size=0;
    5 T5 m/ u% n/ h3 }' I6 e3 R) H
  9.    uint16_t haed_len=0;
    : [( P+ x! ^7 ?8 h& B% j
  10.    sprintf(buffer, "HTTP/1.1 200 OK\r\n"\
    1 Y- i( i8 d8 l" g, T
  11.    "Connection: Keep-Alive\r\n"\
    9 T$ ]# I0 J' K7 p7 |
  12.    "Server: MJPG-Streamer/0.2\r\n"\
    9 W- w! L. V. e: _. j5 K. U
  13.    "Cache-Control:no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0\r\n"\2 V& B: {+ n0 s1 B8 J5 O
  14.    "Pragma:no-cache\r\n"\
    ; y5 h5 s. N$ W
  15.    "Expires:WED, 23 Jan 2019 01:00:00 GMT\r\n"\
    2 |  Y  j& j' y6 G
  16.    "Content-Type: multipart/x-mixed-replace;boundary=openmcu\r\n\r\n"\
    3 K3 n( y8 [. m4 J6 T
  17.    "--openmcu\r\n"); 7 e5 Y- q+ E2 E! i$ e
  18.                               
    2 ~5 a( v; u) Z- N# _/ P1 O
  19.     haed_len=strlen(buffer);0 n1 W3 y# J5 K
  20.    //printf("\r\n%s\r\n",buffer);' o. R3 i2 m. c4 r5 V. ~  ^4 j
  21.    if(send(client, buffer,haed_len, 0)==-1)! ?$ ^6 m0 p6 A+ s- E, z( y
  22.    {+ L& o" z3 w+ ~& s' U
  23.       return HTTP_FAIL;
    6 k  m/ h! `. I" z0 M# P0 O
  24.    }+ l$ v# H3 M4 M& i
  25.   #if USE_CAMERA- ~- K3 u2 S- n- q7 v
  26.   frame_size=jpeg_data_len(); 5 e" n% c0 V9 B% g* v
  27.   if(frame_size==0) return HTTP_FAIL;
    5 Z; f# g4 t& u- i0 O! K  W
  28.   #else1 b2 T4 B" r9 H6 E
  29.   if(count==0)  ]- O9 i: {# _' E
  30.   frame_size=sizeof(cam_data);( E7 q* v, Y, ^$ t# e# i0 |
  31.   else if(count==1)3 |+ i5 O4 a: Q7 Q0 G1 h$ F
  32.   frame_size=sizeof(cam_data2);
    : a1 I* t1 o4 v
  33.   #endif         
    , b5 D# x. x. b% O  g; f
  34.   haed_len=strlen(buffer);
    ( V+ e$ @# l: N$ t" a3 W  J
  35. 5 F7 t  z1 X# w) T+ N
  36.   sprintf(buffer, "Content-Type: image/jpeg\r\n"\6 B7 Q: I+ u1 j  h/ x! T. c% ~5 M6 T' y
  37.   "Content-Length: %d\r\n\r\n", frame_size);+ k* p0 W9 D* a1 b- U: \" q
  38.   printf("\r\n%s\r\n",buffer);
    ; Y; r8 f7 r1 v7 D
  39.   haed_len=strlen(buffer);5 i. b! g1 A5 D0 \2 N9 H
  40.   if(send(client, buffer,haed_len, 0)==-1)6 M  p  B+ ^3 g
  41.   {; @! H, q& t6 M4 Q2 E
  42.      return HTTP_FAIL;* ]6 S% m* ^' v2 e
  43.    }1 A+ N: a9 a* ^4 r6 Z
  44.   #if USE_CAMERA" l1 T2 }( R5 D2 W4 z! E
  45.   memcpy(&buffer[haed_len],(char*)ptr,frame_size);
    9 N1 W- Z% `1 }
  46.   #else( C& j: F6 `/ C" i
  47.   if(count==0)
    3 B" Z$ J0 j, T6 ]4 z/ G7 ?; t
  48.   memcpy(&buffer[haed_len],(char*)cam_data,frame_size);
    ' U7 w* O, [+ F" k
  49.   else if(count==1)$ d. a4 V. i; y6 F
  50.   memcpy(&buffer[haed_len],(char*)cam_data2,frame_size);
    $ p6 j9 w* b+ Q/ t& N; J
  51.   #endif                 
    3 r0 n1 e8 Y  w( y) U
  52.   if(send(client, &buffer[haed_len],frame_size, 0)==-1)) e8 u, S  X# J. z" B, q
  53.   {
    . K7 q3 `8 c* t* T8 k. H
  54.      return HTTP_FAIL;
    ) ?0 [. U, T! z$ [0 z$ |7 S0 F
  55.   }
    2 I' R) [  J3 {$ l! Q
  56.   #if USE_CAMERA8 I& i/ k) W: a& c* c0 d5 E: R
  57.        newframe=0;  & t. ]4 T$ y+ R: J* a+ ~
  58.        cam_start();         ( E% O0 F* c7 B& ]" ~  _" }3 C; j5 y
  59.   #endif
    ; T) w1 ~% v7 j/ ~3 L7 K
  60.       //lwip_close(client);                " S: c" |' Y0 z- L% e
  61.   return HTTP_OK;
    4 n  J4 U, s, n: `
  62. }
复制代码
5 ], @+ }4 h5 W  I% z6 F8 M# t
发送完第一帧图片后,循环发送前面介绍的图片数据格式,就能看到摄像头的实时画面了。
GIF2.gif
8 F' W8 ?4 [7 X$ ~5 v3 [
测试源码
【】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
学习了,
1 j3 |, S2 A% c# U. ~8 Y2 T) X4 c下次可以和楼主的整合一起
! @% e& L; P6 [" ~4 M将视频实时显示在屏幕上,
: @- q( Q! ~7 N' p, zhttps://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=622494&page=1#pid2473242
" K6 f# y$ L+ O  E3 p6 Q# @) U, h) Q! P8 u8 F
感谢支持下; v7 a- i5 N' }$ g) ]
shanji 回答时间:2019-4-3 10:34:11
yklstudent-1794 发表于 2019-4-3 10:16* b9 k' ^3 w- K) |
楼主请教下,发送数据后就立即关闭连接,之前发送的数据还能发送出去吗? ...

( f0 P, \0 `4 ?9 h/ I关闭连接后发不出去了,需要重新等待客户端的连接。
yklstudent 回答时间:2019-4-3 10:43:01
shanji 发表于 2019-4-3 10:34
0 f7 i5 B# ?5 i( O% q关闭连接后发不出去了,需要重新等待客户端的连接。
! d' T: }7 J8 U9 C, P- o6 a
那为什么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 手机版