FFserver服务器实现WebM格式视频直播

本文介绍如何利用FFmpeg作为WebM格式的流服务器,支持从文件、摄像头或屏幕录制视频流,通过配置FFserver进行音视频内容的实时传输与格式转换。

 WebM格式视频流播放可以通过HTML5在浏览器中实现,目前Chrome和FireFox都已经支持了该视频格式。WebM解码器在VP8引擎中实现,并且针对互联网特点做了很多优化。优点是在HTML5中实现,真正的实现了平台无关性,所有采用VP8引擎的浏览器都可以直接播放WebM格式的视频。当然很多浏览器并非VP8引擎的,而且没有哪个知名的流服务器支持WebM。这也是WebM的窘境。现在介绍一下大名鼎鼎的如何用FFmpeg作为WebM的流服务器。

0. FFserver

 FFserver是一个流服务器,可以帮你将音视频内容转换成流在互联网上传输。它能够收集多个输入流,并转码->重铸->广播每一个流。如下图所示,

 

 多个输入源被“喂”到广播服务器,这些多媒体内容就会分发到多个客户端。上图的目的是显示地表明你的流系统能够被分成多个块部署到网络上,允许你广播不同的在线内容,而不需要改变流媒体系统的结构。

 FFserver有以下四个组成部分:输入源(Input sources)、供稿方(Feeds)、流组件(Streams)、媒体播放器(Media Player)。如下图所示

 

输入源(Input Source)

 输入源并非是ffserver内部结构的一部分,通常倾向于使用外部应用发送音视频流到ffserver。由于FFmpeg大多用于输入源,本文以ffmpeg为例。首先输入源将连接到服务器并将自己绑定给一个供稿方。这里一个供稿方只能绑定一个源,因此只有供稿方未绑定时,才能接入输入源。一个输入源可以允许绑定到多个供稿方,但是只有输入源需要产生多个流媒体时,这样做才是有意义的。输入源提供相同的流媒体给不同的供稿方是无意义的,因为ffserver可以将供稿方提供给不同的流媒体。

供稿方(Feed)

 供稿方是ffserver内部的一个组件,他的目的是将一个输入流绑定给一个或者多个输出流。将一个供稿方绑定给多个输出流是有意义的,因为你可能会需要这个输出流同时输出不同的多媒体格式。简单来说,每一个供稿方逻辑上代表了一个输入流。

流组件(Stream)

 一个流组件是ffserver的一个内部组件,表示一个接入点,任何一个希望观看这个流的客户端都可以接入。举例来讲,对于同一个输入流,如果你希望输出一个高清视频和一个小尺寸的手机视频,你就可以将这个供稿方绑定到两个流组件上。供稿方和刘组件最大的区别是一个流组件可以与客户端建立多条连接,而一个供稿方通常只连接一个流组件。

播放器

 播放器不是ffserver的组成部分,他只是代表了连接到流媒体服务器关心媒体内容的客户端。

 

1. 配置FFserver

 当客户端机器实际的接入时,FFserver将成为一个守护进程。它需要足够的带宽向所有连接的客户端传输视频流。视频流编码通过FFmpeg实现,所以运行FFserver的主机并不需要很强的计算能力。

 下面是FFserver.conf的一个例子,服务器定义了一个Feed和一个Stream。Feed作为流的输入源头,向Stream输出视频。Stream接收来自Feed的流,转码为WebM格式,根据定义的比特率和编解码器实现编码。客户端通过访问Stream就可以获得WebM的直播流。服务器的另一个组件是status.xml,用于观察各个流的状态。

 

Port 8090                      # Port to bind the server to
BindAddress 0.0.0.0
MaxHTTPConnections 2000
MaxClients 1000
MaxBandwidth 10000             # Maximum bandwidth per client
                               # set this high enough to exceed stream bitrate
CustomLog -
NoDaemon                       # Remove this if you want FFserver to daemonize after start

<Feed feed1.ffm>               # This is the input feed where FFmpeg will send
   File ./feed1.ffm            # video stream.
   FileMaxSize 64M              # Maximum file size for buffering video
   ACL allow 127.0.0.1         # Allowed IPs
</Feed>

<Stream test.webm>              # Output stream URL definition
   Feed feed1.ffm              # Feed from which to receive video
   Format webm

   # Audio settings
   AudioCodec vorbis
   AudioBitRate 64             # Audio bitrate

   # Video settings
   VideoCodec libvpx
   VideoSize 720x576           # Video resolution
   VideoFrameRate 25           # Video FPS
   AVOptionVideo flags +global_header  # Parameters passed to encoder
                                       # (same as ffmpeg command-line parameters)
   AVOptionVideo cpu-used 0
   AVOptionVideo qmin 10
   AVOptionVideo qmax 42
   AVOptionVideo quality good
   AVOptionAudio flags +global_header
   PreRoll 15
   StartSendOnKey
   VideoBitRate 400            # Video bitrate
</Stream>

<Stream status.html>            # Server status URL
   Format status
   # Only allow local people to get the status
   ACL allow localhost
   ACL allow 192.168.0.0 192.168.255.255
</Stream>

<Redirect index.html>    # Just an URL redirect for index
   # Redirect index.html to the appropriate site
   URL http://www.ffmpeg.org/
</Redirect>

 ffserver启动时默认查看 /etc/ffserver.conf 配置文件,你可以通过-f选项控制查阅的配置文件。

ffserver -f ffserver.conf

运行结果如下图,这样ffserver就成功启动了。

 

 打开http://localhost:8090/status.html可以看到当前server中各个流的状态。

 

2. 向FFserver接入视频流

 FFserver启动之后,需要向http://localhost:8090/feed1.ffm接入视频流。注意,这里不需要指定编码格式,FFserver会重新编码。

 视频流的来源可以是文件、摄像头或者录制屏幕。

 1 比如从文件获得一个视频流并接入到FFM中。

 ffmpeg -i testvideo.mp4 http://localhost:8090/feed1.ffm

 这样ffmpeg将从testvideo中获取视频,并发送到feed1.ffm中,然后Stream对feed1.ffm编码。如果希望ffmpeg以视频预设的帧率来feed数据,就需要用-re命令强制按照时间戳feed视频数据。如

ffmpeg -re -i testvideo.mp4 http://localhost:8090/feed1.ffm

 运行结果如下:

ffmpeg version N-56125-gb4e1630-syslin Copyright (c) 2000-2013 the FFmpeg developers
  built on Sep  9 2013 15:23:52 with gcc 4.4.7 (Ubuntu/Linaro 4.4.7-2ubuntu1)
  configuration: --prefix=/usr/local/ffmpeg --enable-shared --enable-nonfree --enable-gpl --enable-pthreads --disable-yasm --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libfaac --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-libvpx --enable-x11grab --extra-cflags=-I/usr/local/ffmpeg/include/ --extra-ldflags=-L/usr/local/ffmpeg/lib --enable-version3 --extra-version=syslin
  libavutil      52. 43.100 / 52. 43.100
  libavcodec     55. 31.101 / 55. 31.101
  libavformat    55. 16.101 / 55. 16.101
  libavdevice    55.  3.100 / 55.  3.100
  libavfilter     3. 84.100 /  3. 84.100
  libswscale      2.  5.100 /  2.  5.100
  libswresample   0. 17.103 /  0. 17.103
  libpostproc    52.  3.100 / 52.  3.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'testvideo.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 1
    compatible_brands: isomavc1
    creation_time   : 2013-07-14 17:16:27
  Duration: 00:03:14.75, start: 0.000000, bitrate: 392 kb/s
    Stream #0:0(und): Video: h264 (Constrained Baseline) (avc1 / 0x31637661), yuv420p, 320x240 [SAR 1:1 DAR 4:3], 255 kb/s, 20 fps, 20 tbr, 20k tbn, 40 tbc (default)
    Metadata:
      creation_time   : 2013-07-14 17:16:27
      handler_name    : mctemp69368b9542f0253c7.264#video:fps=20:par=1:1 - Imported with GPAC 0.5.0-rev4065
    Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 135 kb/s (default)
    Metadata:
      creation_time   : 2013-07-14 17:16:27
      handler_name    : GPAC ISO Audio Handler
[libvpx @ 0x9bd940] v1.1.0
Output #0, ffm, to 'http://localhost:8090/feed1.ffm':
  Metadata:
    major_brand     : isom
    minor_version   : 1
    compatible_brands: isomavc1
    creation_time   : now
    encoder         : Lavf55.16.101
    Stream #0:0(und): Audio: vorbis (libvorbis), 22050 Hz, mono, fltp, 64 kb/s (default)
    Metadata:
      creation_time   : 2013-07-14 17:16:27
      handler_name    : GPAC ISO Audio Handler
    Stream #0:1(und): Video: vp8 (libvpx), yuv420p, 720x576 [SAR 16:15 DAR 4:3], q=10-42, 400 kb/s, 1000k tbn, 20 tbc (default)
    Metadata:
      creation_time   : 2013-07-14 17:16:27
      handler_name    : mctemp69368b9542f0253c7.264#video:fps=20:par=1:1 - Imported with GPAC 0.5.0-rev4065
Stream mapping:
  Stream #0:1 -> #0:0 (aac -> libvorbis)
  Stream #0:0 -> #0:1 (h264 -> libvpx)
Press [q] to stop, [?] for help
frame=   11 fps=1.9 q=0.0 size=       4kB time=00:00:00.41 bitrate=  78.9kbits/s
frame=   13 fps=2.0 q=0.0 size=       4kB time=00:00:00.41 bitrate=  78.9kbits/s
frame=   16 fps=2.2 q=0.0 size=       4kB time=00:00:00.41 bitrate=  78.9kbits/s
frame=   18 fps=2.2 q=0.0 size=       4kB time=00:00:00.41 bitrate=  78.9kbits/s
frame=   19 fps=2.1 q=0.0 size=       4kB time=00:00:00.43 bitrate=  74.8kbits/s
frame=   22 fps=2.3 q=0.0 size=       4kB time=00:00:00.90 bitrate=  36.3kbits/s
frame=   25 fps=2.4 q=0.0 size=      16kB time=00:00:00.90 bitrate= 145.2kbits/s
frame=   26 fps=2.2 q=0.0 size=      20kB time=00:00:00.90 bitrate= 181.5kbits/s
frame=   27 fps=2.2 q=0.0 size=      20kB time=00:00:00.90 bitrate= 181.5kbits/s
frame=   35 fps=2.7 q=0.0 size=      24kB time=00:00:01.39 bitrate= 141.4kbits/
......
View Code

 2 录制屏幕并接入到FFM中

ffmpeg -f x11grab -r 25 -s 640x512 -i :0.0 -f alsa -i pulse http://localhost:8090/feed1.ffm

 这里有两个-f,第一个指的是视频流,第二个指的是音频流。视频流是抓取屏幕形成视频,-r设置帧率为25帧/s,-s设置抓取图像大小为640x512,-i设置录制视频的初始坐标。音频流设置为alsa(Advanced Linux Sound Architecture),从Linux系统中获取音频。这其中这样ffmpeg可以录制屏幕feed到feed1.ffm中。运行结果如下:

ffmpeg version N-56125-gb4e1630-syslin Copyright (c) 2000-2013 the FFmpeg developers
  built on Sep  9 2013 15:23:52 with gcc 4.4.7 (Ubuntu/Linaro 4.4.7-2ubuntu1)
  configuration: --prefix=/usr/local/ffmpeg --enable-shared --enable-nonfree --enable-gpl --enable-pthreads --disable-yasm --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libfaac --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-libvpx --enable-x11grab --extra-cflags=-I/usr/local/ffmpeg/include/ --extra-ldflags=-L/usr/local/ffmpeg/lib --enable-version3 --extra-version=syslin
  libavutil      52. 43.100 / 52. 43.100
  libavcodec     55. 31.101 / 55. 31.101
  libavformat    55. 16.101 / 55. 16.101
  libavdevice    55.  3.100 / 55.  3.100
  libavfilter     3. 84.100 /  3. 84.100
  libswscale      2.  5.100 /  2.  5.100
  libswresample   0. 17.103 /  0. 17.103
  libpostproc    52.  3.100 / 52.  3.100
[x11grab @ 0x221d280] device: :0.0 -> display: :0.0 x: 0 y: 0 width: 640 height: 512
[x11grab @ 0x221d280] shared memory extension found
Input #0, x11grab, from ':0.0':
  Duration: N/A, start: 1378727353.224054, bitrate: 314258 kb/s
    Stream #0:0: Video: rawvideo (BGR[0] / 0x524742), bgr0, 640x512, 314258 kb/s, 29.97 tbr, 1000k tbn, 29.97 tbc
Guessed Channel Layout for  Input Stream #1.0 : stereo
Input #1, alsa, from 'pulse':
  Duration: N/A, start: 1378727353.299919, bitrate: 1536 kb/s
    Stream #1:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
[swscaler @ 0x21ff040] deprecated pixel format used, make sure you did set range correctly
[libvpx @ 0x225e100] v1.1.0
Output #0, ffm, to 'http://localhost:8090/feed1.ffm':
  Metadata:
    creation_time   : now
    encoder         : Lavf55.16.101
    Stream #0:0: Audio: vorbis (libvorbis), 22050 Hz, mono, fltp, 64 kb/s
    Stream #0:1: Video: vp8 (libvpx), yuv420p, 720x576, q=10-42, 400 kb/s, 1000k tbn, 29.97 tbc
Stream mapping:
  Stream #1:0 -> #0:0 (pcm_s16le -> libvorbis)
  Stream #0:0 -> #0:1 (rawvideo -> libvpx)
Press [q] to stop, [?] for help
frame=   22 fps=0.0 q=0.0 size=       4kB time=00:00:00.44 bitrate=  73.0kbits/s
frame=   37 fps= 36 q=0.0 size=     160kB time=00:00:00.92 bitrate=1411.3kbits/s
frame=   51 fps= 33 q=0.0 size=     220kB time=00:00:01.28 bitrate=1405.5kbits/s
frame=   66 fps= 32 q=0.0 size=     284kB time=00:00:01.40 bitrate=1660.1kbits/s
......
View Code

 3 从摄像头获取视频发送到feed1.ffm中

ffmpeg -f video4linux2 -s 640x480 -r 25 -i /dev/video0 -f alsa -i pulse http://localhost:8090/feed1.ffm

 video4linux2是负责从摄像头中获取视频的插件,/dev/video0就是摄像头映射的文件。运行结果如下

ffmpeg version N-56125-gb4e1630-syslin Copyright (c) 2000-2013 the FFmpeg developers
  built on Sep  9 2013 15:23:52 with gcc 4.4.7 (Ubuntu/Linaro 4.4.7-2ubuntu1)
  configuration: --prefix=/usr/local/ffmpeg --enable-shared --enable-nonfree --enable-gpl --enable-pthreads --disable-yasm --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libfaac --enable-libmp3lame --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-libvpx --enable-x11grab --extra-cflags=-I/usr/local/ffmpeg/include/ --extra-ldflags=-L/usr/local/ffmpeg/lib --enable-version3 --extra-version=syslin
  libavutil      52. 43.100 / 52. 43.100
  libavcodec     55. 31.101 / 55. 31.101
  libavformat    55. 16.101 / 55. 16.101
  libavdevice    55.  3.100 / 55.  3.100
  libavfilter     3. 84.100 /  3. 84.100
  libswscale      2.  5.100 /  2.  5.100
  libswresample   0. 17.103 /  0. 17.103
  libpostproc    52.  3.100 / 52.  3.100
[video4linux2,v4l2 @ 0xdc03c0] The V4L2 driver changed the video from 640x512 to 640x480
[video4linux2,v4l2 @ 0xdc03c0] The driver changed the time per frame from 1/25 to 1/30
Input #0, video4linux2,v4l2, from '/dev/video0':
  Duration: N/A, start: 415.173405, bitrate: 147456 kb/s
    Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 640x480, 147456 kb/s, 30 fps, 30 tbr, 1000k tbn, 1000k tbc
Guessed Channel Layout for  Input Stream #1.0 : stereo
Input #1, alsa, from 'pulse':
  Duration: N/A, start: 1378794986.966378, bitrate: 1536 kb/s
    Stream #1:0: Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s
[libvpx @ 0xde7f20] v1.1.0
Output #0, ffm, to 'http://172.26.176.6:8090/video.ffm':
  Metadata:
    creation_time   : now
    encoder         : Lavf55.16.101
    Stream #0:0: Audio: vorbis (libvorbis), 22050 Hz, mono, fltp, 64 kb/s
    Stream #0:1: Video: vp8 (libvpx), yuv420p, 720x576, q=10-42, 400 kb/s, 1000k tbn, 25 tbc
Stream mapping:
  Stream #1:0 -> #0:0 (pcm_s16le -> libvorbis)
  Stream #0:0 -> #0:1 (rawvideo -> libvpx)
Press [q] to stop, [?] for help
frame=   15 fps=0.0 q=0.0 size=       4kB time=00:00:00.42 bitrate=  77.5kbits/s
frame=   27 fps= 27 q=0.0 size=      16kB time=00:00:00.79 bitrate= 165.8kbits/s
frame=   40 fps= 27 q=0.0 size=      32kB time=00:00:01.27 bitrate= 205.4kbits/s
......
View Code 

参考:

https://www.virag.si/2012/11/streaming-live-webm-video-with-ffmpeg/

http://trac.ffmpeg.org/wiki/Streaming%20media%20with%20ffserver

转载于:https://www.cnblogs.com/hongyanee/p/3310087.html

内容由流媒体协议等基本知识,视频媒体基本知识,流媒体服务器搭建实战,流媒体工具使用实战等内容组成。由本人“天地会珠海分舵”(http://blog.youkuaiyun.com/zhubaitian)耗时一个月整理而成,现分享给大家。 章节内容分布如下: 第1章Streaming 协议和服务器概览学习摘录 7 1.1 Protocol support 8 1.2 Media Container format support 12 第2章Streaming 协议学习摘录 15 2.1 MMS协议简介 15 2.2 RTP相关协议简介 15 2.2.1 RTP与RTCP协议简介 15 2.2.2 RTSP协议简介 16 2.2.3 流传输过程 17 2.3 RTMP vs RTMFP 18 2.3.1 RTMP协议简介 18 2.3.3 RTMFP 简介 19 2.3.4 RTMP VS RTMFP 20 2.4 MPEG-TS 20 2.4.1 MPEG2-TS与MPEG2-PS的区别 20 2.4.2 PES/ES/TS简介 20 2.5 Smooth Streaming 21 2.5 HLS简介 24 2.6 MPEG-DASH 26 2.6.1 简介 26 2.6.2 Dash播放器列表 28 2.6.3 MPD格式 30 2.6.5 MPD在线检查器 31 2.6.5 MPD 格式理解个人小结 31 2.6.6 PMD格式的多样性 32 2.6.7 MPD 支持的Profiles 44 2.6.8 DASH传输协议支持 44 2.7 HLS VS MPEG-DASH 45 2.8 Real Data Transport Protocol 45 2.9 webM 45 第3章 视频容器格式学习摘录 47 3.1 视频容器VS 视频编码 47 3.2 3GP容器 48 3.2 AVI容器(.avi) 49 3.3 WMV vs ASF 容器(.wmv/.asf) 49 3.3.1 ASF高级串流格式简介以及和WMA/WMV的区别 49 3.3.2 ASF和WMA/WMV的区别官方解析 50 3.4 QuickTime容器(.mov) 50 3.5 Ogg vs Ogm容器(.ogg) 51 3.5.1 Ogg容器格式 51 3.5.2 Ogm 51 3.5.3 Ogg vs Ogm 52 3.6 Matroska容器(.mkv|.mka|.mks) 52 3.7 MP4容器 53 3.7.1 简介 53 3.7.2 MP4格式详解 53 3.8 MPEGE TS容器 61 3.9 FLV容器 62 3.10 ABS – Adaptive Bitrate Streaming 自适应串流容器 62 3.11 码率 63 3.12 流媒体的3种格式 63 3.12.1 压缩媒体文件格式 63 3.12.2 流文件格式 64 3.12.3 流媒体发布格式 64 第4章 视频编码格式学习摘录 66 4.1视频编码格式简介 66 4.2主流视频编码格式比较 67 4.2.1 MPEG编码格式 67 4.2.2 DivX/XviD编码格式 68 4.2.3 H.264/X264编码格式 69 4.2.4 WMA-HD/VC-1编码格式 71 4.2.5 各主流编码格式比较 72 4.3 视频解码 73 第5章ffmpeg学习摘录 74 5.1 简介 74 5.2 功能 74 5.3 支持的格式和编码 75 5.4 支持的流媒体协议 76 5.5 ffmpeg视频解码架构示例简略 76 5.5.1 解复用(Demux) 77 5.5.2 解码 (Decode) 78 5.5.3 Ffmpeg中解码流程对应的API函数 78 第6章GStreamer学习摘录 80 6.1 GStreamer简介 80 6.2 GStreamer编写MP3播放器实例 80 6.2.1 初始化GStreamer 80 6.2.2 创建GStreamer管道元件 81 6.2.3 创建元件三元组之GStreamer数据源 81 6.2.4 创建元件三元组之解码器 (即GStreamer过滤器) 插件 81 6.2.5 创建元件三元组之GStreamer接收器 81 6.2.6 链接GStreamer元件三元组到管道 – 播放 82 6.2.7 启动GStreamer管道数据处理流程 82 6.2.8 MP3命令行播放器源代码完整实例 82 第7章 ffmpeg VS GStreamer比较学习摘录 85 7.1 Pipeline设计模式简介 85 7.2 ffmpeg vs GStreamer 86 7.2.1 网上解析翻译 86 7.2.1 FFmpeg和GStreamer异同小结 87 第8章 流媒体服务器搭建摘录 88 8.1 VLC 88 8.1.1 VLC编码和容器兼容性 88 8.1.1 VLC 配置VOD点播 88 8.1.2 VLC 配置组播服务器 90 8.2 Wowza Streaming Engine 91 8.2.1 简介及安装 91 8.2.2 MPEG-DASH 支持 92 8.2.3 如何使用VLC作为直播源 95 8.2.4 点播VOD配置 112 8.3 Nex Gen Media Server (NGMS) 114 8.3.1 Introduction 114 8.3.2 Feature List 115 8.3.3 Practice in Action 116 8.4 IIS Smooth Streaming(IIS Media Service) 117 8.4.1 Getting Started with IIS Smooth Streaming 117 8.4.2 Use VLC to play the Smooth Stream 128 8.4.3 创建Smooth Stream 文件 129 8.4.4 提供DASH服务时IIS的关键设置 129 8.4.5 Dash on IIS步骤 130 第9章 相关工具学习摘录 137 9.1 Bento4 MP4工具包 137 9.1.1 Introduction 137 9.1.2 所包含的工具简介 138 9.1.3 MPEG DASH Adaptive Streaming 139 9.1.4 Serving DASH Streams 147 9.2 MP4Box 149 9.2.1 简介 149 9.2.2 对DASH的支持命令帮助 150 9.2.3 MP4Box: fragmentation, segmentation, splitting and interleaving 153 9.2.4 把MP4转换成TS 155 9.2.5生成不同profile的MPD 155 9.2.6指定每个Representation的bandwidth 156 9.2.7生成多个period的MPD 156 9.2.8生成多个Representation的MPD 156 9.2.9 生成多个Segment的MPD 156 9.2.10 生成(Subsegment) SegmentBase拥有 indexRangeExact 为true的MPD 157 9.2.11 生成多个AdaptionSet的MPD 158 9.2.12 模拟live直播 158 第10章 流媒体服务器搭建指导 159 10.1 所需搭建服务器Matrix 159 第11章 附录 163 11.1 Wowza支持格式 163 11.2 ISO Base Media File Format (IBMFF) 163 11.3 DASH所支持Profile分类 164
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值