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

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

[复制链接]
shanji 发布时间:2019-4-1 17:58
本帖最后由 shanji 于 2019-4-27 09:03 编辑
5 w- _* C0 Y" n9 A8 X4 w4 L- T8 B  m- d  f' F+ ]; V8 h6 D4 H
https://www.stmcu.org.cn/module/forum/thread-609701-1-1.html
$ T. g) m+ `& S, C  u距上次分享了个网络摄像头的示例也有一段时间了,用的裸TCP协议,这次来玩玩不同的花样,网页摄像头mjpeg-stream传输,用HTTP协议。网上搜了下,清一色的在Linux下实现的,在单片机上实现的还真没找到,为了玩起来,只能琢磨linux下的代码。
. i8 I. M% V# T1 E( _* k- H" f7 r        一、先把网页做出来* i" K- b/ b% x: j6 k
      网页端的实现比较简单,用img标签,例:
; V( `) D0 B1 H! c3 N& S+ }+ ?! q* S<html>
( o+ Q) M4 `8 }4 L2 |3 S! l      <head>9 A/ G) H0 s6 t/ W* L$ o- Y
      </head>
- e$ L* F& Q1 V: m- F& P! p* k      <body>1 T$ n( @' @. W' k
      <img src="http://192.168.1.199:80/?stm32=mjpeg">,此处的ip指的是服务器的ip。
  s/ ^/ m5 Z% e8 x% f      </body>
0 H0 ?' ?! ?/ F% n2 E7 R+ w</html>/ z4 g0 i/ e/ S
      二、 服务端的代码实现
+ W3 v6 l3 ?- I" A
      要在网页上看到不断刷新的图片,服务端需要发送如下的相应包0 @( ~; T- a- u2 T% ^- W
     HTTP/1.1 200 OK\r\n9 l0 x1 D. _8 f. D4 N

# I3 ]. Z  [3 Y( W% x7 E" U! n
     Content-Type: multipart/x-mixed-replace;boundary=xxxxxxxx\r\n\r\n   //boundary后面的字段可自行定义
     关于multipart/x-mixed-replace和boundary网上有很多专业解释,我就不copy了,知道怎么用它就对了。
    要发送图片时的数据包格式是
  --xxxxxxxx\r\n
   Content-Type: img/jpeg\r\n
   Content-Length: 2048\r\n\r\n  //此帧图片的大小
   循环发送这样的数据包给网页,网页上就能看到不断刷新的画面了      
   有了上面的基础,就可以开始码代码。
    关键代码:
     程序中使用了RT-Therad RTOS,用socket编程。
  1. **( I( m: j  W, i: {
  2.   * @brief 开始发送流
    # q9 b" w  C* ?! {" B7 A
  3.   * @param  client,count
    / s8 v- k# A/ v$ y; d6 i  T2 d% \
  4.   * @retval None4 e- }7 H% P7 S* {. d
  5.   */6 |. P4 b& H, e: B
  6. HTTP_STA HTTP_Streamer_Start(int client,u8 count)# n5 [% N; B5 ?6 a9 s
  7. {        
    & c+ \. U  a& P0 l
  8.     int frame_size=0;& y; ^) @+ ?9 B( b5 f; _5 E% L) m: i
  9.    uint16_t haed_len=0;' `. B8 g( c8 f. k
  10.    sprintf(buffer, "HTTP/1.1 200 OK\r\n"\0 o3 {. ~; W6 x$ r: J- |9 d9 D/ \
  11.    "Connection: Keep-Alive\r\n"\
    ! F1 [/ t* M$ y
  12.    "Server: MJPG-Streamer/0.2\r\n"\$ ^! b! H. o# w) v7 K" g
  13.    "Cache-Control:no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0\r\n"\
    : R0 `2 M* x! m3 Y  F; a
  14.    "Pragma:no-cache\r\n"\" F* [0 g% [' p/ m5 K! W9 w/ j
  15.    "Expires:WED, 23 Jan 2019 01:00:00 GMT\r\n"\8 ^$ R- ~( B' x* I  i3 _( q
  16.    "Content-Type: multipart/x-mixed-replace;boundary=openmcu\r\n\r\n"\4 I: ^( h2 N% s, C: C) m) Q, G3 _
  17.    "--openmcu\r\n");
    % i% Q( g1 B; x. H! @8 Z5 n. d1 j
  18.                               
    - p3 e5 K' L5 P  v% [
  19.     haed_len=strlen(buffer);3 @: a. w3 w. x$ k; Z- z. M0 u
  20.    //printf("\r\n%s\r\n",buffer);
    ' j' _0 n3 c3 p
  21.    if(send(client, buffer,haed_len, 0)==-1)+ C$ e$ y9 x2 j# k. v1 G+ T
  22.    {
    ; |( o3 u4 z/ z, R; |
  23.       return HTTP_FAIL;4 p7 |' ?- b4 V* Z$ l& h( \
  24.    }
    ! {+ S% ~( U1 V4 n
  25.   #if USE_CAMERA
    ! l, |8 D, h* n* L, P8 O& Y
  26.   frame_size=jpeg_data_len(); ; x+ {7 ~/ O+ T6 E; m
  27.   if(frame_size==0) return HTTP_FAIL;
    0 D8 O# \1 w6 s  p
  28.   #else* l: G$ D- g+ e- [& s: e5 L  ~
  29.   if(count==0)- t7 i1 d0 m5 }5 ~$ c6 S: G4 g! Z7 U
  30.   frame_size=sizeof(cam_data);7 ]3 a" {9 I  Q! H3 d' A+ U' X
  31.   else if(count==1); M7 ?3 V9 O1 R- p- ^* d
  32.   frame_size=sizeof(cam_data2);
    & P1 v, w/ y& W4 a$ [/ l
  33.   #endif         
    & i+ T+ h& b  ^# f4 A
  34.   haed_len=strlen(buffer);
    9 K  y, K& h+ K8 }" ]

  35. $ q! K; Z3 V2 Z
  36.   sprintf(buffer, "Content-Type: image/jpeg\r\n"\
    ' E3 Z, o9 K+ v7 n  G* J6 v
  37.   "Content-Length: %d\r\n\r\n", frame_size);
    * U. m) L( K8 I/ O
  38.   printf("\r\n%s\r\n",buffer);3 ?0 d5 Z2 P" U7 r, `
  39.   haed_len=strlen(buffer);
    ; r2 u7 Y4 i, X' f4 K
  40.   if(send(client, buffer,haed_len, 0)==-1)
    1 x7 p4 y' I( ?" @3 p6 ^
  41.   {2 d3 D! [! ^6 n
  42.      return HTTP_FAIL;* S, X1 {% x; }7 H
  43.    }
    ! Y! z2 _- P8 q7 c  E4 f  K3 o' U  Z
  44.   #if USE_CAMERA  v& o$ m; V/ u; T/ j3 F6 d& Y
  45.   memcpy(&buffer[haed_len],(char*)ptr,frame_size);0 R8 C" R* ]7 t" r
  46.   #else
    5 m, j4 \6 m* Q# M6 G$ M( l
  47.   if(count==0)& K3 F, r, x' |0 W- c$ C
  48.   memcpy(&buffer[haed_len],(char*)cam_data,frame_size);
    ; p. r5 L1 D' M: E
  49.   else if(count==1)
    . ]; \- E2 b9 R4 O
  50.   memcpy(&buffer[haed_len],(char*)cam_data2,frame_size);  F  ~$ k5 _& w6 `
  51.   #endif                 
    ; ]) F5 |1 n1 v6 c5 A
  52.   if(send(client, &buffer[haed_len],frame_size, 0)==-1)0 C/ q* j5 h) M6 l& E: ^: U4 [
  53.   {+ A/ H5 w; z/ [4 V9 k% f1 l; T9 v
  54.      return HTTP_FAIL;/ [# Y7 G6 N" q$ E  s3 n5 F
  55.   }! o& b! C# o8 j% j2 b$ O* \$ g
  56.   #if USE_CAMERA
    $ |& G+ P$ W4 x. F4 T$ A! n8 d
  57.        newframe=0;  
      J* \, ?+ Q3 j, l) V) A  S) o8 |
  58.        cam_start();         
    ) u& W# |. |  @  L: O/ M' T# t
  59.   #endif
    $ f5 ]% H. D8 b% \: f
  60.       //lwip_close(client);               
    8 L0 f9 t. ^* e! Z: E
  61.   return HTTP_OK;
    ( H6 f' ]# p1 x+ s  j
  62. }
复制代码
! d  ~4 g% {: k! n2 \
发送完第一帧图片后,循环发送前面介绍的图片数据格式,就能看到摄像头的实时画面了。
GIF2.gif

% ]* I6 \( V% L
测试源码
【】STM32F429_网络摄像头(网页版)V1.1.rar (1.74 MB, 下载次数: 416)

评分

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

查看全部评分

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

举报

202个回答
昱枫 回答时间:2019-12-19 10:06:22
学习了,: m$ i" Z5 z3 A/ W8 N) f
下次可以和楼主的整合一起
8 D( S0 \/ X( j( E7 N将视频实时显示在屏幕上,
: S' R) {; C  n5 O9 B$ e5 I: X( mhttps://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=622494&page=1#pid2473242
' [8 D. T* Y3 V! J6 h( r% W) R$ Z. r! X- l/ i6 y
感谢支持下, C$ M  q/ [  g+ _8 w1 y* u
shanji 回答时间:2019-4-3 10:34:11
yklstudent-1794 发表于 2019-4-3 10:16( M$ c* [: k) n" ^& y" X3 G
楼主请教下,发送数据后就立即关闭连接,之前发送的数据还能发送出去吗? ...

6 o" {' O( n: V. G( q* H关闭连接后发不出去了,需要重新等待客户端的连接。
yklstudent 回答时间:2019-4-3 10:43:01
shanji 发表于 2019-4-3 10:34+ J, G$ c& w' K- h+ v; Z
关闭连接后发不出去了,需要重新等待客户端的连接。

& `5 R, ]9 M# N" ~9 H+ T7 x. u1 d3 E那为什么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
厉害,学习学习!
Bowen1028 回答时间: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管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版