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

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

[复制链接]
shanji 发布时间:2019-4-1 17:58
本帖最后由 shanji 于 2019-4-27 09:03 编辑
2 o' B2 G# a2 W% v2 w& a) S5 {0 w) I% e4 o
https://www.stmcu.org.cn/module/forum/thread-609701-1-1.html1 q. _7 u+ ]3 M: D2 \
距上次分享了个网络摄像头的示例也有一段时间了,用的裸TCP协议,这次来玩玩不同的花样,网页摄像头mjpeg-stream传输,用HTTP协议。网上搜了下,清一色的在Linux下实现的,在单片机上实现的还真没找到,为了玩起来,只能琢磨linux下的代码。
4 }7 u5 n" q, I! S, P        一、先把网页做出来) [* Z0 \+ C' _- _# m
      网页端的实现比较简单,用img标签,例:& Q( C: G3 l* }5 |9 V
<html>1 O/ {2 Y, P- H# t
      <head>5 H1 o4 W1 \  L7 P0 y" f
      </head>
. @/ p1 ~8 [' I2 n+ r      <body>
8 v. X; J) n9 Y( v  H, f* H      <img src="http://192.168.1.199:80/?stm32=mjpeg">,此处的ip指的是服务器的ip。
6 n( y( E4 g, p% K" y- x      </body>8 u- y1 r) [/ M7 F6 l
</html>
6 X/ M$ _: M* k) }$ ^      二、 服务端的代码实现2 u; F6 g3 T, Z% \# v. d, Z
      要在网页上看到不断刷新的图片,服务端需要发送如下的相应包+ F: A+ s: M, g6 k$ e$ E
     HTTP/1.1 200 OK\r\n6 n4 \" \- N1 ^+ H9 Q. S

0 \+ ^$ a: e* }( h
     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. **/ j- {4 J% T" Y& U+ U1 Z5 [
  2.   * @brief 开始发送流
    . S& ]3 ^! q* q1 Z; z( p' C5 [
  3.   * @param  client,count
    / O  }" j3 v: ?( e; n6 e9 q4 Q
  4.   * @retval None2 A+ X( E& g8 M, E, V4 l9 g
  5.   */
    * A1 d+ X5 s8 j- k6 `- D5 Q
  6. HTTP_STA HTTP_Streamer_Start(int client,u8 count)
    + \; r: J  c7 Q8 Y4 ~
  7. {        
    % v/ {6 }: j$ R
  8.     int frame_size=0;
    % L! \9 T- I6 R  _: Y6 A3 S
  9.    uint16_t haed_len=0;
    ( K2 I! J4 }. N, K$ e# u
  10.    sprintf(buffer, "HTTP/1.1 200 OK\r\n"\
      R% o- U- c6 ]: [
  11.    "Connection: Keep-Alive\r\n"\
    ) n; ]5 [- W4 ]- j& @
  12.    "Server: MJPG-Streamer/0.2\r\n"\
    . L& Q* H8 E  s2 T  }0 b
  13.    "Cache-Control:no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0\r\n"\
    . g/ ~  w' {' X& E
  14.    "Pragma:no-cache\r\n"\
    , M7 G1 v2 M/ S' s, p* j
  15.    "Expires:WED, 23 Jan 2019 01:00:00 GMT\r\n"\
    / n* x* h! {( G3 b1 i( b# K
  16.    "Content-Type: multipart/x-mixed-replace;boundary=openmcu\r\n\r\n"\- O  v# q1 K% Y8 b* h
  17.    "--openmcu\r\n"); * u& C5 Y5 d( c) l' C: [
  18.                               . v5 }4 @; {8 C6 Q
  19.     haed_len=strlen(buffer);- `4 t; `( x( u
  20.    //printf("\r\n%s\r\n",buffer);, \7 i" R2 i7 E* F' a
  21.    if(send(client, buffer,haed_len, 0)==-1)# a+ T6 C# e0 N  k/ U1 x' _  d
  22.    {
    0 r; m& a9 B! H
  23.       return HTTP_FAIL;
    & o: k) E' |* x' e
  24.    }
    , m. A: W# ~3 ?) d, Y: r1 D
  25.   #if USE_CAMERA" n+ H8 i7 k; y# V$ E5 d% q
  26.   frame_size=jpeg_data_len();
    9 W) f& H+ P' E5 K1 m
  27.   if(frame_size==0) return HTTP_FAIL;
    2 w, H- M7 R" j% C
  28.   #else& [4 y' n* Y7 S3 @
  29.   if(count==0)
    1 ], G8 d" W; ]
  30.   frame_size=sizeof(cam_data);
      o5 l  R1 I: t* B
  31.   else if(count==1)1 K. d9 m8 r4 S( |7 l3 i
  32.   frame_size=sizeof(cam_data2);. D- l5 H5 O4 W7 Y
  33.   #endif          & k. u; X0 O) V! q
  34.   haed_len=strlen(buffer);
    ! w% K) }) X. m5 z; Z

  35. 3 N0 R% f- k: T; c9 e* Z  _
  36.   sprintf(buffer, "Content-Type: image/jpeg\r\n"\
    ' |! n) g/ v1 V; V$ R5 z& D; u4 n
  37.   "Content-Length: %d\r\n\r\n", frame_size);$ a# ]. n! i1 k# {+ X- i
  38.   printf("\r\n%s\r\n",buffer);
    . E- P/ M- _0 K" p8 e
  39.   haed_len=strlen(buffer);: |( e6 c1 c+ x
  40.   if(send(client, buffer,haed_len, 0)==-1)
    9 y# d5 A' N) n. H7 Y" R2 ~
  41.   {
    ' _& w+ u- h) Q: m  h; l
  42.      return HTTP_FAIL;. w3 h; H* _, y1 x5 }2 H
  43.    }
    $ @3 f7 z$ _) D9 W" W% d
  44.   #if USE_CAMERA
    . ^* T# m! o. v2 j9 Q
  45.   memcpy(&buffer[haed_len],(char*)ptr,frame_size);
    - g4 J/ ]9 L# H# T3 R! Z7 J
  46.   #else/ R: v9 r& R9 O3 L& p
  47.   if(count==0)2 |6 u. K3 |* C; i* W
  48.   memcpy(&buffer[haed_len],(char*)cam_data,frame_size);( X$ Q) o9 L3 b% W/ A
  49.   else if(count==1)
    . c9 d2 \! O( H( R
  50.   memcpy(&buffer[haed_len],(char*)cam_data2,frame_size);
    , _$ l' I1 B$ l& C, @
  51.   #endif                 
    . {/ f1 C  |& q: H' D
  52.   if(send(client, &buffer[haed_len],frame_size, 0)==-1)
    ; _2 b; ~. C. X3 {+ J
  53.   {+ x) M9 ~6 l1 k: n9 n" t+ w
  54.      return HTTP_FAIL;: g3 K- b( C1 ^0 W; W
  55.   }
      F$ \7 L* y4 }- m/ O" _2 e1 z5 j/ m: z
  56.   #if USE_CAMERA. N- `3 z9 n1 R9 I$ p; e% [
  57.        newframe=0;  - n& U; V% D- k  S" a, A( g+ F
  58.        cam_start();           h( i- h4 ~# k& O3 K& s
  59.   #endif+ t7 Z8 n% v1 \( B' |2 l: c
  60.       //lwip_close(client);                / Q7 `$ h* a- A8 x0 o# |4 b8 n
  61.   return HTTP_OK;+ N/ D0 R8 b' B, Y& L( h/ X
  62. }
复制代码
1 O  w0 ?1 w& |
发送完第一帧图片后,循环发送前面介绍的图片数据格式,就能看到摄像头的实时画面了。
GIF2.gif
( p, o: M* z0 y2 M& `1 F- B7 `
测试源码
【】STM32F429_网络摄像头(网页版)V1.1.rar (1.74 MB, 下载次数: 354)

评分

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

查看全部评分

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

举报

202个回答
昱枫 回答时间:2019-12-19 10:06:22
学习了,: Z" M( l5 F& N% o7 y0 L
下次可以和楼主的整合一起
8 Z6 }0 R. e0 P% X' l; i, A" f将视频实时显示在屏幕上,% r; \3 l$ o% T: ~
https://www.stmcu.org.cn/module/forum/forum.php?mod=viewthread&tid=622494&page=1#pid2473242
4 N. Z$ h# H6 N1 ^% ~8 d" f, a1 c, Q0 z, q7 x2 }- ]* g' f  Q
感谢支持下
" ]+ q( w! o; P- o
shanji 回答时间:2019-4-3 10:34:11
yklstudent-1794 发表于 2019-4-3 10:16
% H3 p) G3 @" P3 t楼主请教下,发送数据后就立即关闭连接,之前发送的数据还能发送出去吗? ...

( g" h2 [+ ~7 p& _  i( H关闭连接后发不出去了,需要重新等待客户端的连接。
yklstudent 回答时间:2019-4-3 10:43:01
shanji 发表于 2019-4-3 10:34& Y8 d! a7 G4 x: A3 O1 A
关闭连接后发不出去了,需要重新等待客户端的连接。

& `  E% [+ p. V, @$ x那为什么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 手机版