当前位置:黑鲸出海 > 热点资讯 > 干货分享 >  在Cloudflare上构建您的下一个视频应用程序

在Cloudflare上构建您的下一个视频应用程序

发表时间:2022-02-10  来源:cloudflare  作者:Jonathan Kuperman & Adam J  浏览:次  
本文将构建一个受Cloudflare TV启发的视频应用程序。我们将提供用户身份验证,管理员可以上传录制的视频或直播新内容。

YjE0OTdjMS5qcGVn.jpg

过去,构建视频应用程序十分困难。在录制、编码和播放视频背后有许多复杂的技术。幸运的是,Cloudflare Stream分担走了所有困难的部分,现在您可以轻松构建自定义视频和流媒体应用程序。让我们看一下,我们可以如何结合Cloudflare Stream、Access、Pages和Workers,使用极少的代码创建一个高性能的视频应用程序。

今天,我们将构建一个受Cloudflare TV启发的视频应用程序。我们将提供用户身份验证,管理员可以上传录制的视频或直播新内容。能够使用Cloudflare服务打造自己的YouTube或Twich,这多么令人兴奋!

提取视频列表

我们想要在应用程序主页显示所有视频的列表,使用Cloudflare Stream上传和存储的所有视频,之后还会有更多功能!该代码可以更改,以仅显示“热门”视频或为每个用户选择的视频精选。目前,我们将使用搜索API并在一个空字符串中传递以返回全部。

import { getSignedStreamId } from "../../src/cfStream"


export async function onRequestGet(context) {

    const {

        request,

        env,

        params,

    } = context


    const { id } = params


    if (id) {

        const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${env.CF_ACCOUNT_ID}/stream/${id}`, {

            method: "GET",

            headers: {

                "Authorization": `Bearer ${env.CF_API_TOKEN_STREAM}`

            }

        })


        const video = (await res.json()).result


        if (video.meta.visibility !== "public") {

            return new Response(null, {status: 401})

        }


        const signedId = await getSignedStreamId(id, env.CF_STREAM_SIGNING_KEY)


        return new Response(JSON.stringify({

            signedId: `${signedId}`

        }), {

            headers: {

                "content-type": "application/json"

            }

        })

    } else {

        const url = new URL(request.url)

        const res = await (await fetch(`https://api.cloudflare.com/client/v4/accounts/${env.CF_ACCOUNT_ID}/stream?search=${url.searchParams.get("search") || ""}`, {

            headers: {

                "Authorization": `Bearer ${env.CF_API_TOKEN_STREAM}`

            }

        })).json()


        const filteredVideos = res.result.filter(x => x.meta.visibility === "public") 

        const videos = await Promise.all(filteredVideos.map(async x => {

            const signedId = await getSignedStreamId(x.uid, env.CF_STREAM_SIGNING_KEY)

            return {

                uid: x.uid,

                status: x.status,

                thumbnail: `https://videodelivery.net/${signedId}/thumbnails/thumbnail.jpg`,

                meta: {

                    name: x.meta.name

                },

                created: x.created,

                modified: x.modified,

                duration: x.duration,

            }

        }))

        return new Response(JSON.stringify(videos), {headers: {"content-type": "application/json"}})

    }

}

我们将仔细检查每个视频,过滤掉任何私人视频,并抽取出我们需要的元数据,例如缩略图URL、ID和创建日期。

播放视频

要允许用户从我们的应用程序播放视频,则需要公开视频,否则您将需要签署每个请求。将视频标记为“公开”可使整个过程更为简单。然而,可能出于许多原因,您想要控制对视频的访问。如果您希望用户登录后才可播放视频,或者想要能够以任何方式限制访问,可将视频标记为“私人”并使用签名的URL来控制访问。

如果您在本地测试您的应用程序,或希望每天的请求数少于10,000个,您可以调用/token端点以生成一个签名令牌。如果您希望每天超过10,000个请求,请使用JSON Web Tokens签署您自己的令牌,就像我们这里所做的一样。

允许用户上传视频

下一步是构建管理员页面,用户可在其中上传他们的视频。

Cloudflare Stream API使该过程得到了简化。您可使用您的API令牌和帐户ID生成一个唯一的一次性上传URL。仅需确保您的令牌拥有Stream:Edit权限即可。我们从应用程序钩入所有POST请求,并返回生成的上传URL。

export const cfTeamsAccessAuthMiddleware = async ({request, data, env, next}) => {

    try {

        const userEmail = request.headers.get("cf-access-authenticated-user-email")


        if (!userEmail) {

            throw new Error("User not found, make sure application is behind Cloudflare Access")

        }

  

        // Pass user info to next handlers

        data.user = {

            email: userEmail

        }

  

        return next()

    } catch (e) {

        return new Response(e.toString(), {status: 401})

    }

}


export const onRequest = [

    cfTeamsAccessAuthMiddleware

]

管理员页面包含一个表单,允许用户从他们的计算机拖放或上传视频。当一个已登录用户点击上传表单上的“提交”时,应用程序会生成一个唯一的URL,然后向其发布FormData。该代码可有效用于构建视频分享网站或与任何允许用户生成内容的应用程序搭配使用。

async function getOneTimeUploadUrl() {

    const res = await fetch('/api/admin/videos', {method: 'POST', headers: {'accept': 'application/json'}})

    const upload = await res.json()

    return upload.uploadURL

}


async function uploadVideo() {

    const videoInput = document.getElementById("video");


    const oneTimeUploadUrl = await getOneTimeUploadUrl();

    const video = videoInput.files[0];

    const formData = new FormData();

    formData.append("file", video);


    const uploadResult = await fetch(oneTimeUploadUrl, {

        method: "POST",

        body: formData,

    })

}

使用Stream Live添加实时视频

您还可以使用Stream Live,结合我们已经讨论过的技术,向您的应用程序添加直播部分。您可以允许已登录用户开始直播,并允许其他已登录用户(甚至是未登录用户)实时观看!直播内容将自动保存至您的帐户,因此,当直播结束后就可以立即在应用程序的主要区域查看直播内容。

使用中间件保护我们的应用程序

我们将所有经过身份验证的页面都放在此中间件函数后方。它会检查请求标头以确保用户正在发送有效的经过身份验证的用户电子邮件。

export const cfTeamsAccessAuthMiddleware = async ({request, data, env, next}) => {

    try {

        const userEmail = request.headers.get("cf-access-authenticated-user-email")


        if (!userEmail) {

            throw new Error("User not found, make sure application is behind Cloudflare Access")

        }

  

        // Pass user info to next handlers

        data.user = {

            email: userEmail

        }

  

        return next()

    } catch (e) {

        return new Response(e.toString(), {status: 401})

    }

}


export const onRequest = [

    cfTeamsAccessAuthMiddleware

]

使用Pages将所有功能组合起来

我们使用Cloudflare Access来控制我们的登录流程,使用Stream API管理上传、显示和观看视频,使用Workers来管理fetch请求和处理API调用。现在,让我们使用Cloudflare Pages将所有功能结合起来!

Pages提供一种简单的方法来部署和托管静态网站。不过现在,Pages可与Workers平台无缝集成(公告文章链接)。使用该新集成,我们可以使用单个可读存储库来部署这一整个应用程序。

控制访问

一些应用程序更适合公开;另一些应用程序包含敏感数据,应当限制向特定用户开放。此应用程序的主页是公开的,我们已使用Cloudflare Access将管理员页面限制为仅向员工开放。如果您要构建内部学习服务,甚至想要推出新网站的测试版,您都可以轻松使用Access保护您的整个应用程序!

当用户点击我们演示网站上的管理员链接时,将提示他们输入电子邮件地址。如果他们输入有效的Cloudflare电子邮件,则应用程序会向他们发送访问代码。否则,他们将无法访问该页面。

注:文章源自于互联网,如有侵权,请联系客服删除。
19951839869
黑鲸出海客服