请选择 进入手机版 | 继续访问电脑版

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

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

[复制链接]
shanji 发布时间:2019-4-1 17:58
本帖最后由 shanji 于 2019-4-27 09:03 编辑
/ Q' @4 m* ~& S0 [, ?# Y) Q
1 M, ~  b4 ~( @1 A9 k1 ?https://www.stmcu.org.cn/module/forum/thread-609701-1-1.html% k! U( d2 N6 }$ n
距上次分享了个网络摄像头的示例也有一段时间了,用的裸TCP协议,这次来玩玩不同的花样,网页摄像头mjpeg-stream传输,用HTTP协议。网上搜了下,清一色的在Linux下实现的,在单片机上实现的还真没找到,为了玩起来,只能琢磨linux下的代码。2 S% t& L0 j3 d3 Q
        一、先把网页做出来
* l# x: E. ^' W) q: U5 A      网页端的实现比较简单,用img标签,例:
" b/ N/ S! M) T; A3 L<html>
( T; S& [% Z3 H4 f) c$ p/ d      <head>2 t; ~& v9 l1 \4 g) t
      </head>
2 c/ p' d- F  E; I) B, Z1 J      <body>, C' {( V& _4 ~  k( y; o& T
      <img src="http://192.168.1.199:80/?stm32=mjpeg">,此处的ip指的是服务器的ip。/ G+ _, d- {) l) D! q' @
      </body>( b$ m( A* |7 l7 j1 Z
</html>! }; R0 P( B! ?, |5 }; d
      二、 服务端的代码实现; n9 q, O0 a  }: ~5 R
      要在网页上看到不断刷新的图片,服务端需要发送如下的相应包
  h6 X7 p5 @) P& k  T1 U     HTTP/1.1 200 OK\r\n
) z! x* N$ c  ^9 d1 e, q) y2 ], 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. **+ e+ N5 W& M3 `( i1 U3 n
  2.   * @brief 开始发送流# s; v- N- H- t8 C  l5 O
  3.   * @param  client,count
    7 n/ ]( o6 q0 q$ O
  4.   * @retval None
    ) H  ]! d( D$ L3 [& k% F
  5.   */# M# N6 L! c- O# h' z/ G1 F1 R
  6. HTTP_STA HTTP_Streamer_Start(int client,u8 count)
    5 U$ N# z) F9 j- |6 r, u' `) P  {
  7. {        
    1 A* Q# j6 Z- S, i; B: ?
  8.     int frame_size=0;) Z6 u1 f1 |. x) l' e+ z
  9.    uint16_t haed_len=0;
    5 Y/ G3 @) i* Q. i1 r; D* f. ^
  10.    sprintf(buffer, "HTTP/1.1 200 OK\r\n"\
    6 @& e" r: @5 U3 f9 u
  11.    "Connection: Keep-Alive\r\n"\
    5 [) o% L& O8 z& o, x
  12.    "Server: MJPG-Streamer/0.2\r\n"\5 E( ?6 w/ W, z8 x
  13.    "Cache-Control:no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0\r\n"\
    * E( t. z: _4 o' {7 j) G
  14.    "Pragma:no-cache\r\n"\% `/ a/ j3 X( ?
  15.    "Expires:WED, 23 Jan 2019 01:00:00 GMT\r\n"\
    4 T8 Q& O) I& h+ K
  16.    "Content-Type: multipart/x-mixed-replace;boundary=openmcu\r\n\r\n"\& Q" I% G! Z4 d( `/ T+ Q
  17.    "--openmcu\r\n");
    ; {  k: N0 E% m
  18.                               
    ! B, U" ?) Y: n' \6 y8 A) Z" x
  19.     haed_len=strlen(buffer);
    , {7 T9 a& R6 Y
  20.    //printf("\r\n%s\r\n",buffer);
    ; W" w7 p3 W2 T; Z9 R0 [
  21.    if(send(client, buffer,haed_len, 0)==-1)
    , h4 ]0 ?1 @* r, n# }
  22.    {
    , w7 B! V! X3 t, o. V
  23.       return HTTP_FAIL;$ I8 ]2 G1 @; G& s& v
  24.    }
    ' \5 n$ l) R4 y6 \: l
  25.   #if USE_CAMERA/ n% M7 g5 s! X+ ]0 b
  26.   frame_size=jpeg_data_len();
    6 j3 u0 X! d4 C; V5 M$ g2 x" V; }
  27.   if(frame_size==0) return HTTP_FAIL;
    0 k. ]" \( p) s6 j/ b
  28.   #else# Y3 k- u4 _( F$ O! h
  29.   if(count==0)
    ) \) q4 |. |: K: ?8 G3 [* n& Q
  30.   frame_size=sizeof(cam_data);
    2 o7 M! V& V: G$ K5 }
  31.   else if(count==1)7 g: a1 O/ [4 x, ^! t' V- O+ g# b
  32.   frame_size=sizeof(cam_data2);
    / n% M0 E8 l/ y/ M2 V
  33.   #endif          3 \( \( ~9 ~/ u( b2 Z
  34.   haed_len=strlen(buffer);
    ' \8 z/ T" W9 @) }- Q2 \. p, b

  35. & X3 k4 f0 [  v; S! E/ B
  36.   sprintf(buffer, "Content-Type: image/jpeg\r\n"\
    * g% S+ ?  m2 M/ U* _2 T" {6 z
  37.   "Content-Length: %d\r\n\r\n", frame_size);% V& p" z- b+ ^4 z' T5 R
  38.   printf("\r\n%s\r\n",buffer);
    & Y$ ]. F" P: R" x# e
  39.   haed_len=strlen(buffer);7 n; B4 J" \# `2 r# X0 h6 f
  40.   if(send(client, buffer,haed_len, 0)==-1)
    % m+ b' Y4 A5 M- F* k8 A0 U
  41.   {
    & C% U9 y8 q7 v; v8 E( c
  42.      return HTTP_FAIL;
    - F  K. c4 D3 U9 C3 h
  43.    }
    3 _: U% `9 }! K5 @$ a
  44.   #if USE_CAMERA2 F# [0 m6 I4 D: c' S# [0 A* I" s
  45.   memcpy(&buffer[haed_len],(char*)ptr,frame_size);
    4 Q2 @1 r  `% i5 G6 T
  46.   #else2 y- B# n% n  @1 f
  47.   if(count==0)
      u& j0 s7 _6 e: R5 S* L
  48.   memcpy(&buffer[haed_len],(char*)cam_data,frame_size);& i7 I4 z4 e: m0 _; a" H* |/ |# w
  49.   else if(count==1)7 x7 L1 l6 Z: e" O
  50.   memcpy(&buffer[haed_len],(char*)cam_data2,frame_size);$ d% J$ w, T5 b6 X" W! T  z
  51.   #endif                 ! a0 N* Q$ f2 S3 {6 H
  52.   if(send(client, &buffer[haed_len],frame_size, 0)==-1); c/ U9 ?& S" p1 m& b5 y) L
  53.   {) G5 `, `$ O$ N8 f8 f& }: @# [' J
  54.      return HTTP_FAIL;  c! S" l! d( C& d$ D
  55.   }
    9 U2 d8 s( X" x( J' _) Z+ h: h% H
  56.   #if USE_CAMERA
    ( ?# o0 o. q! ~4 l' b2 e
  57.        newframe=0;  
    - f6 W6 O9 u  v1 J& N4 ]& u" I  g
  58.        cam_start();         
    , T4 i/ z7 a. T7 h
  59.   #endif3 }0 Z( o0 I* t# N9 Q
  60.       //lwip_close(client);               
    ( ?$ L+ b) V& v. v6 l, ]
  61.   return HTTP_OK;  m/ q& H5 Q# C$ t5 U% I7 g' |
  62. }
复制代码

1 y- t( P! T( e  b- |( O) m# O
发送完第一帧图片后,循环发送前面介绍的图片数据格式,就能看到摄像头的实时画面了。
GIF2.gif

% e+ M! [+ X+ a3 L! W
测试源码
【】STM32F429_网络摄像头(网页版)V1.1.rar (1.74 MB, 下载次数: 352)

评分

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

查看全部评分

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

举报

202个回答
昱枫 回答时间:2019-12-19 10:06:22
学习了,
. ?* R, i* U3 \下次可以和楼主的整合一起
: r, R/ h# Q) p0 D将视频实时显示在屏幕上,
2 \0 n8 E% m  F; Khttps://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=622494&page=1#pid24732422 L: a/ F" E5 f9 x4 X

" l9 _2 ^# |3 E8 h6 ]8 i感谢支持下, N4 T3 n# d$ ^% N
shanji 回答时间:2019-4-3 10:34:11
yklstudent-1794 发表于 2019-4-3 10:16. b8 h3 h9 P, l0 ^  ]
楼主请教下,发送数据后就立即关闭连接,之前发送的数据还能发送出去吗? ...

, a' F) r) ?$ ?5 k5 C6 c0 e4 B( Q关闭连接后发不出去了,需要重新等待客户端的连接。
yklstudent 回答时间:2019-4-3 10:43:01
shanji 发表于 2019-4-3 10:34
6 o- O! h, S" @  A2 Z9 @关闭连接后发不出去了,需要重新等待客户端的连接。

" F, e, v3 e; g# h! v6 j3 Q那为什么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 手机版