几种开源的媒体服务器对比
<h2>1 概念</h2> <h2>1.1 RTP</h2> <p><a href="/misc/goto?guid=4959757743985035074" rel="nofollow,noindex">实时传输协议 - 维基百科,自由的百科全书</a></p> <p>实时传输协议(Real-time Transport Protocol或简写RTP)是一个网络传输协议,它是由IETF的多媒体传输工作小组1996年在RFC 1889中公布的。</p> <p>RTP协议详细说明了在互联网上传递音频和视频的标准数据包格式。它一开始被设计为一个多播协议,但后来被用在很多单播应用中。RTP协议常用于流媒体系统(配合RTSP协议),视频会议和一键通(Push to Talk)系统(配合H.323或SIP),使它成为IP电话产业的技术基础。RTP协议和RTP控制协议RTCP一起使用,而且它是创建在 <strong>UDP</strong> 协议上的。</p> <h2>1.2 RTMP</h2> <p><a href="/misc/goto?guid=4959757744081903025" rel="nofollow,noindex">实时消息协议 - 维基百科,自由的百科全书</a></p> <p>实时消息协议(英语:Real-Time Messaging Protocol,缩写RTMP)也称实时消息传输协议,是最初由Macromedia为通过互联网在Flash播放器与一个服务器之间传输流媒体音频、视频和数据而开发的一个专有协议。Macromedia后被Adobe Systems收购,该协议也已发布了不完整的规范供公众使用。</p> <p>RTMP协议有许多变种:</p> <ol> <li>默认使用TCP端口1935的纯粹(plain)协议。</li> <li><strong>RTMPS</strong> ,通过一个TLS/SSL连接传输RTMP。</li> <li><strong>RTMPE</strong> ,使用Adobe自有安全机制加密的RTMP。虽然实现的细节为专有,但该机制使用行业标准的密码学原函数。</li> <li><strong>RTMPT</strong> ,用HTTP封装以穿透防火墙。RTMPT通常在TCP通信端口80和443上使用明文请求来绕过大多数的公司流量过滤。封装的会话中可能携带纯粹的RTMP、RTMPS或RTMPE数据包。</li> <li><strong>RTMFP</strong> , 使用UDP而非TCP的RTMP,取代RTMP Chunk Stream。Adobe Systems开发了安全的实时媒体流协议包,可以让最终用户直接地相互连接(P2P)。</li> </ol> <h2>1.3 WebRTC</h2> <p><a href="/misc/goto?guid=4959757744161073735" rel="nofollow,noindex">https://webrtc.org/</a></p> <p>WebRTC is a free, open projectthat provides browsers and mobile applications with <em>Real-Time Communications (RTC)</em> capabilities via simple APIs. The WebRTC components have been optimized to best serve this purpose.</p> <p>Our mission: To enable rich, high-quality RTC applications to be developed for the browser, mobile platforms, and IoT devices, and allow them all to communicate via a common set of protocols.</p> <p>The WebRTC initiative is a project supported by <strong>Google</strong> , <strong>Mozilla</strong> and <strong>Opera</strong> , amongst others.</p> <p>支持的浏览器和平台:</p> <ul> <li>Chrome</li> <li>Firefox</li> <li>Opera</li> <li>Android</li> <li>iOS</li> </ul> <p>特点:</p> <ul> <li>基于浏览器,且主流浏览器都支持,跨平台能力强</li> <li>默认P2P,但是需要TURN服务器作为fallback</li> <li>自适应码率 <ul> <li><a href="/misc/goto?guid=4959757744242636534" rel="nofollow,noindex">webrtc 视频编码之 h264 自动调节分辨率 — newrtc</a></li> <li><a href="/misc/goto?guid=4959757744331765023" rel="nofollow,noindex">webm - Does WebRTC support Adaptive Bitrate Streaming for video? - Stack Overflow</a></li> </ul> </li> </ul> <p>相关资料:</p> <ul> <li><a href="/misc/goto?guid=4959757744403136912" rel="nofollow,noindex">2013 Google I/O 大会上WebRTC的幻灯片</a></li> <li><a href="/misc/goto?guid=4959757744491233548" rel="nofollow,noindex">Getting Started with WebRTC - Sam Dutton</a></li> <li><a href="/misc/goto?guid=4959757744571370094" rel="nofollow,noindex">WebRTC in the real world: STUN, TURN and signaling - Sam Dutton</a></li> <li><a href="/misc/goto?guid=4959757744667919401" rel="nofollow,noindex">IETF Real-Time Communication in WEB-browsers (rtcweb) Working Group</a></li> <li><a href="/misc/goto?guid=4959757744744964942" rel="nofollow,noindex">RFC7742 - WebRTC Video Processing and Codec Requirements</a></li> </ul> <h2>1.4 HLS</h2> <p><a href="/misc/goto?guid=4959757744831391767" rel="nofollow,noindex">HTTP Live Streaming - 维基百科,自由的百科全书</a></p> <p>HTTP Live Streaming(缩写是HLS)是一个由苹果公司提出的基于HTTP的流媒体网络传输协议。它的工作原理是把整个流分成一个个小的基于HTTP的文件来下载,每次只下载一些。当媒体流正在播放时,客户端可以选择从许多不同的备用源中以不同的速率下载同样的资源,允许流媒体会话适应不同的数据速率。在开始一个流媒体会话时,客户端会下载一个包含元数据的extended M3U (m3u8) playlist文件,用于寻找可用的媒体流。</p> <p>HLS只请求基本的HTTP报文,与实时传输协议(RTP)不同,HLS可以穿过任何允许HTTP数据通过的防火墙或者代理服务器。它也很容易使用内容分发网络(CDN)来传输媒体流。</p> <p>2017年8月, <a href="/misc/goto?guid=4959757744936564116" rel="nofollow,noindex">RFC 8216</a> 发布,描述了HLS协议第7版的定义</p> <p><a href="/misc/goto?guid=4959757744936564116" rel="nofollow,noindex">RFC 8216</a></p> <h2>2 开源方案</h2> <h2>2.0 开源方案选型要考虑的因素:</h2> <p><a href="/misc/goto?guid=4959757745026749151" rel="nofollow,noindex">10 Tips for Choosing the Right WebRTC Open Source Media Server Framework </a></p> <ol> <li>你是否深刻理解其代码?</li> <li>代码版本是否足够新?</li> <li>有谁在使用它?</li> <li>它的文档是否齐全?</li> <li>它可以debug吗?</li> <li>它可以伸缩吗?</li> <li>它使用哪种语言? <ul> <li>对于媒体服务器而言,这种语言的性能是否足够?</li> <li>团队是否足够了解这门语言?</li> </ul> </li> <li>是否适应你现有的Signaling范式? <ul> <li>你在看的Media Server是否容易与你决定使用的STUN/TURN服务器集成</li> </ul> </li> <li>许可证是否适合你?</li> <li>谁在提供支持? <ul> <li>很多成功的、被良好维护的开源项目背后都有一个商业模式,尤其是中小型的项目,这意味着有一个团队以此为谋生手段。</li> <li>具备可选的付费支持意味着: <ul> <li>有人愿意全职来改善这东西,而不是作为爱好来维护。</li> <li>如果你需要紧急帮助,只要花钱就能得到。</li> </ul> </li> </ul> </li> </ol> <h2>2.1 Red5</h2> <p>官网 <a href="/misc/goto?guid=4959757745114080748" rel="nofollow,noindex">http://red5.org/</a></p> <p>Github <a href="/misc/goto?guid=4959757745201919907" rel="nofollow,noindex">https://github.com/Red5</a></p> <p>非官方资料:</p> <ul> <li><a href="/misc/goto?guid=4959757745291259277" rel="nofollow,noindex">red5-development-series</a></li> </ul> <p>特性:</p> <ul> <li>Server <ul> <li>自动伸缩集群</li> <li>Adaptive Stream Rebuffering</li> <li>支持多协议: <ul> <li>WebRTC</li> <li>RTMP</li> <li>RTSP</li> <li>HLS</li> <li>FLV</li> <li>MP4</li> </ul> </li> <li>实时流录制</li> <li>离线部署</li> </ul> </li> <li>Browser <ul> <li>定制化HTML5播放器,支持旋转</li> <li>实时HLS流</li> <li>支持Flash作为后备方案</li> </ul> </li> <li>移动端SDK(iOS, Android) <ul> <li>自适应比特率发布</li> <li>硬件编码和解码</li> <li>定制视频源</li> <li>直播摄像头切换</li> <li>双路视频聊天</li> <li>多方视频会议</li> <li>Adaptive Stream Rebuffering</li> <li>低延迟播放器</li> <li>高级通知API</li> <li>消息与RPC</li> <li>HD h.264, AAC编码高达4k</li> </ul> </li> </ul> <p>粗略的特性收费情况调查结果:</p> <table> <thead> <tr> <th>-</th> <th>开源版本</th> <th>付费版本</th> </tr> </thead> <tbody> <tr> <td>自动伸缩集群</td> <td>不支持</td> <td>\$279/MO</td> </tr> <tr> <td>多协议支持</td> <td>支持</td> <td>支持</td> </tr> <tr> <td>转码</td> <td>不支持</td> <td>\$109/MO</td> </tr> <tr> <td>离线部署</td> <td>支持</td> <td>\$999+/MO</td> </tr> </tbody> </table> <p>来自 <a href="/misc/goto?guid=4959757745380348847" rel="nofollow,noindex">Red5 open source vs Red5pro · rajdeeprath/red5-development-series Wiki</a> 的数据</p> <table> <thead> <tr> <th>FEATURES</th> <th>RED5 OS</th> <th>RED5 PRO</th> </tr> </thead> <tbody> <tr> <td>实时流</td> <td>✔</td> <td>✔</td> </tr> <tr> <td>视频录制</td> <td>✔</td> <td>✔</td> </tr> <tr> <td>WebSockets</td> <td>✔</td> <td>✔</td> </tr> <tr> <td>移动端回放(HLS)</td> <td>Community</td> <td>✔</td> </tr> <tr> <td>Adobe Flash 支持</td> <td>✔</td> <td>✔</td> </tr> <tr> <td>WebRTC</td> <td>✖</td> <td>✔</td> </tr> <tr> <td>第二屏</td> <td>✖</td> <td>✔</td> </tr> <tr> <td>自动伸缩</td> <td>✖</td> <td>✔</td> </tr> <tr> <td>集群</td> <td>✖</td> <td>✔</td> </tr> <tr> <td>移动端SDK</td> <td>✖</td> <td>✔</td> </tr> <tr> <td>扩展文档</td> <td>✖</td> <td>✔</td> </tr> <tr> <td>客户支持</td> <td>Community</td> <td>✔</td> </tr> <tr> <td>管理API (RESTful)</td> <td>✖</td> <td>✔</td> </tr> </tbody> </table> <p>缺点:</p> <ul> <li>开源版本很难用,官方几乎没有文档,即使有,也是几年前的了,也没有教程。</li> </ul> <p>考察点总结:</p> <table> <thead> <tr> <th>考察点</th> <th>OS</th> <th>PRO</th> </tr> </thead> <tbody> <tr> <td>语言</td> <td>Java</td> <td>Java</td> </tr> <tr> <td>最新发布日期</td> <td>2017-01-12</td> <td>?</td> </tr> <tr> <td>谁在用</td> <td>?</td> <td>Intel, LimeLight,…,etc(最经典的方案)</td> </tr> <tr> <td>文档</td> <td>✖</td> <td>✔</td> </tr> <tr> <td>伸缩</td> <td>✖</td> <td>✔</td> </tr> <tr> <td>debug</td> <td>?</td> <td>?</td> </tr> <tr> <td>许可证</td> <td>Apache License v2</td> <td>付费</td> </tr> <tr> <td>网络协议</td> <td>HLS, WebSockets, RTSP, RTMP, RTMPT, RTMPS, RTMPE</td> <td>HLS, WebSockets, RTSP, RTMP, RTMPT, RTMPS, RTMPE, WebRTC</td> </tr> <tr> <td>自适应码率</td> <td>?</td> <td>✔</td> </tr> <tr> <td>流控</td> <td>?</td> <td>?</td> </tr> <tr> <td>录制</td> <td>?</td> <td>✔</td> </tr> <tr> <td>回放</td> <td>?</td> <td>✔</td> </tr> </tbody> </table> <h2>2.2 kurento</h2> <p>主页: <a href="/misc/goto?guid=4959757745466022091" rel="nofollow,noindex">http://www.kurento.org/</a></p> <p>github: <a href="/misc/goto?guid=4959757745545437527" rel="nofollow,noindex">https://github.com/kurento</a></p> <p>服务端采用C++实现: <a href="/misc/goto?guid=4959757745633814788" rel="nofollow,noindex">https://github.com/Kurento/kurento-media-server</a></p> <p>特性:</p> <ul> <li>支持HTTP、RTP和WebRTC</li> <li>集成OpenCV,支持分析图像抽取信息</li> <li>转码(这个是刚需了)</li> <li>广播</li> <li>提供Kurento API,可以在此基础上构建服务器的高层逻辑,并提供了Java和NodeJS的实现,基于此可以实现权限校验等业务逻辑</li> <li>支持NAT穿越</li> </ul> <p>文档地址: <a href="/misc/goto?guid=4959757745731276774" rel="nofollow,noindex">http://readthedocs.org/projects/doc-kurento/downloads/pdf/stable/</a></p> <p>考察点总结:</p> <table> <thead> <tr> <th>考察点</th> <th>情况</th> </tr> </thead> <tbody> <tr> <td>语言</td> <td>C++</td> </tr> <tr> <td>最新发布日期</td> <td>2018-03-21</td> </tr> <tr> <td>谁在用</td> <td>没有业界权威在用,Github 800+Star</td> </tr> <tr> <td>文档</td> <td>比较全</td> </tr> <tr> <td>伸缩</td> <td>✖</td> </tr> <tr> <td>debug</td> <td>?</td> </tr> <tr> <td>许可证</td> <td>LGPL v2.1</td> </tr> <tr> <td>网络协议</td> <td>HTTP, RTP, WebRTC</td> </tr> <tr> <td>自适应码率</td> <td>✔</td> </tr> <tr> <td>流控</td> <td>?</td> </tr> <tr> <td>录制</td> <td>✔</td> </tr> <tr> <td>回放</td> <td>✔</td> </tr> </tbody> </table> <h2>2.3 RestComm</h2> <p>官网 <a href="/misc/goto?guid=4959757745818009238" rel="nofollow,noindex">https://www.restcomm.com/</a></p> <p>GitHub <a href="/misc/goto?guid=4959757745906527426" rel="nofollow,noindex">https://github.com/RestComm</a></p> <p>文档 <a href="/misc/goto?guid=4959757745990064393" rel="nofollow,noindex">https://www.restcomm.com/docs/</a></p> <p>免费版本功能受限</p> <p><img src="https://simg.open-open.com/show/d8087007c42be9fcda5c8967a52273f4.jpg"></p> <p>考察点总结:</p> <table> <thead> <tr> <th>考察点</th> <th>情况</th> </tr> </thead> <tbody> <tr> <td>语言</td> <td>Java</td> </tr> <tr> <td>最新发布日期</td> <td>2018-04-20</td> </tr> <tr> <td>谁在用</td> <td>?</td> </tr> <tr> <td>文档</td> <td>齐全</td> </tr> <tr> <td>伸缩</td> <td>付费</td> </tr> <tr> <td>debug</td> <td>?</td> </tr> <tr> <td>许可证</td> <td>AGPL-3.0</td> </tr> <tr> <td>网络协议</td> <td>WebRTC</td> </tr> <tr> <td>自适应码率</td> <td>✔</td> </tr> <tr> <td>流控</td> <td>?</td> </tr> <tr> <td>录制</td> <td>?</td> </tr> <tr> <td>回放</td> <td>?</td> </tr> </tbody> </table> <h2>2.4 Ant Media Server</h2> <p>官网 <a href="/misc/goto?guid=4959757746077272873" rel="nofollow,noindex">https://antmedia.io/</a></p> <p>文档 <a href="/misc/goto?guid=4959757746148017678" rel="nofollow,noindex">https://antmedia.io/documentation</a></p> <p>Github <a href="/misc/goto?guid=4959757746238799858" rel="nofollow,noindex">https://github.com/ant-media/ant-media-server</a></p> <p><a href="/misc/goto?guid=4959757746323645738" rel="nofollow,noindex">Star</a> <a href="/misc/goto?guid=4959757746409316707" rel="nofollow,noindex">Fork</a></p> <p>服务端采用Java实现,是Red5-server的分叉版本</p> <p>特性:</p> <ul> <li>实时流发布</li> <li>支持RTMP、RTSP、WebRTC、HLS</li> <li>WebRTC转RTMP适配器</li> <li>IP摄像头支持</li> <li>录制实时流(FLV、MP4和HLS容器)</li> <li>同步重制流到社交媒体(企业版里非死book和油Tube)</li> <li>低延迟1:N WebRTC实时流(企业版)</li> <li>实时流自适应比特率转换(FLV、MP4、HLS)(企业版)</li> </ul> <p>考察点总结:</p> <table> <thead> <tr> <th>考察点</th> <th>情况</th> </tr> </thead> <tbody> <tr> <td>语言</td> <td>Java</td> </tr> <tr> <td>最新发布日期</td> <td>2018-05-01</td> </tr> <tr> <td>谁在用</td> <td> </td> </tr> <tr> <td>文档</td> <td>齐全</td> </tr> <tr> <td>伸缩</td> <td>收费</td> </tr> <tr> <td>debug</td> <td>?</td> </tr> <tr> <td>许可证</td> <td>Apache License v2</td> </tr> <tr> <td>网络协议</td> <td>RTMP、RTSP、WebRTC、HLS</td> </tr> <tr> <td>自适应码率</td> <td>✔</td> </tr> <tr> <td>流控</td> <td>?</td> </tr> <tr> <td>录制</td> <td>✔</td> </tr> <tr> <td>回放</td> <td>✔</td> </tr> </tbody> </table> <h2>2.5 BigBlueButton</h2> <p>官网 <a href="/misc/goto?guid=4959757746495851116" rel="nofollow,noindex">https://bigbluebutton.org/</a></p> <p>文档 <a href="/misc/goto?guid=4959757746583041269" rel="nofollow,noindex">http://docs.bigbluebutton.org/</a></p> <p>github <a href="/misc/goto?guid=4959757746665073452" rel="nofollow,noindex">https://github.com/bigbluebutton/bigbluebutton</a></p> <p><a href="/misc/goto?guid=4959757746665073452" rel="nofollow,noindex">Star</a> <a href="/misc/goto?guid=4959757746755484885" rel="nofollow,noindex">Fork</a></p> <p>采用Java开发,主要针对场景是授课</p> <p>特性:</p> <ul> <li>实时添加字幕</li> <li>屏幕共享</li> <li>分组讨论室</li> <li>录制与回放</li> </ul> <p>考察点总结:</p> <table> <thead> <tr> <th>考察点</th> <th>情况</th> </tr> </thead> <tbody> <tr> <td>语言</td> <td>Java</td> </tr> <tr> <td>最新发布日期</td> <td> </td> </tr> <tr> <td>谁在用</td> <td> </td> </tr> <tr> <td>文档</td> <td> </td> </tr> <tr> <td>伸缩</td> <td> </td> </tr> <tr> <td>debug</td> <td> </td> </tr> <tr> <td>许可证</td> <td> </td> </tr> <tr> <td>网络协议</td> <td> </td> </tr> <tr> <td>自适应码率</td> <td> </td> </tr> <tr> <td>流控</td> <td> </td> </tr> <tr> <td>录制</td> <td> </td> </tr> <tr> <td>回放</td> </tr> </tbody> </table> <h2>2.6 NextRTC</h2> <p>主页 <a href="/misc/goto?guid=4959757746839631111" rel="nofollow,noindex">https://nextrtc.org/</a></p> <p>Github <a href="/misc/goto?guid=4959757746917964857" rel="nofollow,noindex">https://github.com/mslosarz/nextrtc-signaling-server</a></p> <p>考察点总结:</p> <table> <thead> <tr> <th>考察点</th> <th>情况</th> </tr> </thead> <tbody> <tr> <td>语言</td> <td>Java</td> </tr> <tr> <td>最新发布日期</td> <td>2018-04-05</td> </tr> <tr> <td>谁在用</td> <td>(估计没人)</td> </tr> <tr> <td>文档</td> <td>简单</td> </tr> <tr> <td>伸缩</td> <td>✔</td> </tr> <tr> <td>debug</td> <td>✔</td> </tr> <tr> <td>许可证</td> <td>MIT</td> </tr> <tr> <td>网络协议</td> <td>WebRTC</td> </tr> <tr> <td>自适应码率</td> <td>✔</td> </tr> <tr> <td>流控</td> <td>✖</td> </tr> <tr> <td>录制</td> <td>✖</td> </tr> <tr> <td>回放</td> <td>✖</td> </tr> </tbody> </table> <h2>2.7 OpenBroadcaster</h2> <p><a href="/misc/goto?guid=4959757747001965964" rel="nofollow,noindex">https://obsproject.com/</a></p> <p><a href="/misc/goto?guid=4959757747086289877" rel="nofollow,noindex">https://github.com/obsproject</a></p> <p>TBD</p> <p><a href="/misc/goto?guid=4959757747161334606" rel="nofollow,noindex">Comparison of streaming media systems - Wikipedia</a></p> <table> <thead> <tr> <th>名称</th> <th>创建者</th> <th>最新稳定版(发布日期)</th> <th>最新发布日期</th> <th>价钱 (USD)</th> <th>许可证</th> <th>支持媒体</th> </tr> </thead> <tbody> <tr> <td>Cameleon</td> <td>Yatko</td> <td>1.0.7 (2016-11-11)</td> <td>2016-11-11</td> <td>Free</td> <td>专有</td> <td>Audio/Video</td> </tr> <tr> <td>Helix Universal Server</td> <td>RealNetworks</td> <td>15.2.1 (2014-09-16)</td> <td>2014-09-16</td> <td>Free for 12 months (Basic) and \$1,000-\$10,000</td> <td>专有</td> <td>Audio/Video</td> </tr> <tr> <td>IIS Media Services</td> <td>Microsoft</td> <td>4.1 (2011-11-09)</td> <td>2011-11-09</td> <td>Free</td> <td>专有</td> <td>Audio/Video/Data</td> </tr> <tr> <td>Nimble Streamer</td> <td>WMSPanel</td> <td>2.15.1-3 (2016-03-21)</td> <td>2016-03-21</td> <td>Free</td> <td>专有</td> <td>Audio/Video</td> </tr> <tr> <td>Open Broadcaster Software</td> <td>OBS Project</td> <td>0.657 (2015-11-24)</td> <td>2015-11-24</td> <td>Free</td> <td>GPL v2</td> <td>Audio/Video</td> </tr> <tr> <td>OpenBroadcaster</td> <td>OpenBroadcaster</td> <td>5.0.0 (2018-01-27)</td> <td>2018-01-27</td> <td>Free</td> <td>AGPLv3</td> <td>Audio/Video</td> </tr> <tr> <td>Plex (software)</td> <td>Plex Media Server</td> <td>1.0.3.2461-35f0caa (2016-07-28)</td> <td>2016-07-28</td> <td>Free</td> <td>GPL</td> <td>Audio/Video</td> </tr> <tr> <td>Red5 (open source)</td> <td>Infrared5/community</td> <td>1.0.6 (2015-09-08)</td> <td>2015-09-08</td> <td>Free</td> <td>Apache License v2</td> <td>Audio/Video/Data</td> </tr> <tr> <td>Unified Streaming Platform</td> <td>Unified Streaming</td> <td>1.7.18 (2016-04-11)</td> <td>2016-04-11</td> <td>Free Trial license; Perpetual License; Amazon EC2 with embedded license; Microsoft Azure</td> <td>专有</td> <td>Audio/Video</td> </tr> <tr> <td>Unreal Media Server</td> <td>Unreal Streaming Technologies</td> <td>12.0 (2017-04-03)</td> <td>2017-04-03</td> <td>\$995 perpetual license</td> <td>专有</td> <td>Audio/Video</td> </tr> <tr> <td>VLC media player</td> <td>VideoLAN</td> <td>2.2.4 (2016-06-05)</td> <td>2016-06-05</td> <td>Free</td> <td>GPL v2</td> <td>Audio/Video</td> </tr> <tr> <td>Wowza Streaming Engine</td> <td>Wowza Media Systems</td> <td>4.5.0 build 18676 (2016-06-23)[2]</td> <td>2016-06-23</td> <td>Free Developer and Trial licenses; Subscription Licenses at \$65/month; Perpetual Pro License at \$1995; Amazon EC2 with embedded license starting at \$0.15/hour</td> <td>专有</td> <td>Audio/Video/Data</td> </tr> </tbody> </table> <p>-</p> <p> </p> <p>来自:http://bungder.github.io/2018/05/06/compare-of-some-open-source-media-server/</p> <p> </p>
本文由用户 javase 自行上传分享,仅供网友学习交流。所有权归原作者,若您的权利被侵害,请联系管理员。
转载本站原创文章,请注明出处,并保留原始链接、图片水印。
本站是一个以用户分享为主的开源技术平台,欢迎各类分享!