从头开始构建Cloudflare电视

2020-07-08 06:31:24

CloudFlare TV的灵感来自于90年代的电视节目,这些节目分享了计算机和音乐视频领域最新、最令人兴奋的发展。我们对Cloudflare电视有三个基本要求:

所有事情都应该在云中进行,我们永远不需要要求任何人“让他们的计算机开着”才能让流一天24小时运行。

白手起家地构建Cloudflare电视背后的许多技术并不是计划的一部分,特别是考虑到我们咄咄逼人的时间表。那么,我们为什么决定追查它呢?在评估了多种直播解决方案后,我们得出了以下结论:

对于大多数视频流平台来说,24x7线性流不是优先考虑的事情。这是有道理的:视频点播和基于事件的直播的兴起是以牺牲线性流媒体为代价的。

大多数广播平台都有自己的访客应用程序,必须提前下载和设置。与点击日历邀请中的链接以加入视频呼叫相比,这引入了不必要的摩擦。

Cloudflare TV的核心目标之一是让演示者更容易,还有什么比让他们使用他们已经知道的工具更容易的呢?我们团队中的每个人都熟悉Zoom,许多将出现在Cloudflare TV上的嘉宾也是如此。更好的是,Zoom几乎总是有效的。

因此,当我们发现Zoom允许您将实时视频推送到任何RTMP端点时,我们开始试验该功能。

“RTMP”代表实时消息传递协议(Real-Time Messaging Protocol),最初是为了通过Macromedia Flash使用TCP实现低延迟通信而开发的。RTMP已经超过了Flash,并被包括YouTube在内的平台广泛使用,以实现视频直播。RTMP是一种推送协议,像YouTube这样的平台提供的RTMP端点仅仅是URL。大多数视频广播应用程序都可以让你配置多个RTMP端点,这会告诉应用程序“嘿,把我手机或电脑上的实时视频发送到这些服务上。”如果您发现自己正在观看多个服务正在播放的直播视频,这很可能是由RTMP实现的。

Zoom允许您提供RTMP端点,并指示它将Zoom调用的实况视频发送到Cloudflare TV的RTMP。在使用此功能之前,我们需要能够接收RTMP视频提要。

apt-get install build-Essential libpcre3libpcre3-dev libssl-dev git zlib1g-dev-ymkdir~/build&;&;cd~/buildgit克隆git://github.com/arut/nginx-rtmp-module.gitwget http://nginx.org/download/nginx-1.14.1.tar.gztar xzf nginx-1.14.1.tar.gzcd nginx-1.14.1sudo./Configure--with-http_ssl_module--add-module=../nginx-rtmp-module。

接下来,我们配置了nginx.conf,以便Nginx不仅可以接收RTMP提要,还可以将其流传输给最终用户。浏览器通常不能从RTMP源进行流媒体传输。我们需要Nginx来获取RTMP提要并创建HLS/DASH段。

我们定义了一个名为live inside nginx.conf的应用程序。在直播应用中,我们可以添加指令来摄取RTMP和输出HLS:

.RTMP{服务器{.。应用LIVE{允许全部播放;LIVE ON;#SAMPLE HLS ON;HLS_PATH/mnt/HLS/;HLS_Fragment 1;HLS_PLAYLIST_LENGTH 4;HLS_SYNC 100ms;}。

一旦我们将Nginx设置为摄取RTMP和HLS,我们就按照Zoom关于Custom Live Streaming的说明进行操作。很快,我们就有了使用Cloudflare网络进行实时流Zoom调用的基本原型!

因此,我们满足了首要要求,即让客人体验像加入视频通话一样简单。但Cloudflare电视不会是一个永无止境的召唤。我们需要一种方法来在一天中的多个呼叫之间平稳过渡,并重放一些我们最喜欢的片段。

例如,我们可能有从1000到1100的现场节目,然后是两个小时的预录(或重放)内容。当实况节目在1100结束时,视频体验将中断,并且用户将需要点击刷新来观看时间表上的下一个节目。

能够设置节目(“What Play When?”)。提前很多天。

让“虚拟房间”接收来自不同来源的视频(现场活动、使用我们的Cloudflare Stream产品存储的预先录制的视频)。

一旦我们有了时间表和“虚拟房间”,我们就可以动态地将当前正在播放的内容切换到适当的“虚拟房间”来流式传输内容。

“勇敢”是英国广播公司发起的一个开源项目。使用Brave,我们能够设置多个虚拟房间,并使任何虚拟房间顺利上线。

每时每刻都在把决赛(“空中补给”)推到Nginx。

Contentful是一个设计为API优先的无头内容管理平台;它消除了对数据库的需要,并帮助我们快速构建我们的日程安排功能。

对于CMS来说,大多数必需的字段都非常简单:标题、演示者,当然还有时间段。其中的每一个都自动与cloudflare.tv/Schedule上面向公众的时间表同步。

导出异步函数fetchEventRaw(id:string){let r=等待获取(`${contentful_api}/entry/${id}`,{Headers:{';Content-Type';:';application/json';,Authorization:`承载${contentful_admin}`,},})return unrapch(r,';无法检索事件';)}

更复杂的部分是将其与Zoom集成。每个细分市场都需要自己的Zoom会议,手动创建这些会议相当困难。因此,当我们在Contful中发布时,Contful会调用一个工作端点。工作人员端点自动生成Zoom会议,并向编程团队提供定制的邀请以发送给来宾。

例如,当新事件添加到Contful时,Contful会通知我们的员工端点创建新会议并对其进行配置,以便将其推送到Cloudflare TV:

导出异步函数createMeeting(EV:TVEevent){const Headers=await zoomHeaders()const Alternative_Hosts=ev.altHosts?ev.altHosts.join(';,';):';';ev.zoomPassword=genPassword()让r=等待fetch(`https://api.zoom.us/v2/users/${ev.studio}@cloudflare.com/meetings`,{Method:';POST';,Header,Body:JSON.stringify({Topic:ev.Title,Type:2,Start_Time:ev.start,Duration:ev.Duration,时区:';utc';,Agenda:ev.description,密码:ev.zoomPassword,设置:{host_video:true,Participant_video:false,Alternative_Hosts,CN_Meeting:false,in_Meeting:false,Join_Beever_host:true,mute_on_entry:true,Watermark:false,use_pmi:false,Approval_type:2,Audio:';Both,AUTO_RECORING:';cloud';,enforce_login:False,},})let Data=等待展开(r,';无法创建缩放会议';)日志(';zoom:';,data)ev.meetingId=data.id ev.zoomUrl=data.join_url//将直播流配置数据推送到会议r=等待fetch(`https://api.zoom.us/v2/meetings/${ev.meetingId}/livestream`,{method:';patch';,Header,Body:JSON.stringify({//TODO:使STREAM_URL:cftv_RTMP_ENDPOINT,STREAM_KEY:ev.studio,page_url:';https://cloudflare.tv';,}),})等待解包(r,';更新实况流配置失败)返回EV}。

使用Content的另一个好处是我们团队的许多成员已经熟悉它,因此它减少了学习新工具的开销。

到目前为止,我们已经描述了使Cloudflare电视成为可能的后端的不同部分(Nginx、Brave、Contful)。我们怎么才能把他们都聚在一起呢?CloudFlare Workers是将这些系统连接在一起的粘合剂。Cloudflare电视前端构建在工作人员站点上。前端调用我们的工作端点来获取数据,比如编程日历。

我们才刚刚开始使用Cloudflare电视。我们有一个很长的愿望清单,上面列出了我们真正想要看到的功能。以下是我们迫不及待想要开发的一些功能:

CloudflareTV直播流缩放RTMP Life@Cloudflare