Tube - AI background jobs

  • background jobs
    • 后臺(tái)工作能很好地幫助我們處理超時(shí)的問題
    • 即使任務(wù)失敗了也可以立即重試
  • upstash workflow
    • 點(diǎn)擊查看 How to use and deploy Upstash Workflow with Next.js?,在當(dāng)前項(xiàng)目中之前使用過upstash redis的rate limit服務(wù)
    • 更新 .env 文件中的 QStash 時(shí),一定要按照文檔提示的位置找到對(duì)應(yīng)變量
    • install 版本:"@upstash/workflow": "^0.2.18"
    • 運(yùn)行工作流節(jié)點(diǎn),使用http請(qǐng)求,curl -X POST http://localhost:3000/api/videos/workflows/title,正常請(qǐng)求成功的話會(huì)拿到一個(gè) workflowRunId,當(dāng)前運(yùn)行這個(gè)節(jié)點(diǎn)只是簡(jiǎn)單的做個(gè)測(cè)試,更重要的是下一步保護(hù)節(jié)點(diǎn)的安全性
    • 保護(hù)工作流節(jié)點(diǎn)的安全性,防止任何人都可以觸發(fā)工作流,配置QStash內(nèi)置的驗(yàn)證請(qǐng)求,最終環(huán)境變量?jī)?nèi)容如下:(配置完成這一步后再運(yùn)行工作流節(jié)點(diǎn)會(huì)提示驗(yàn)證失?。?/li>
    // .env
    
    # Upstash workflow
    UPSTASH_WORKFLOW_URL=...
    QSTASH_TOKEN=...  
    QSTASH_CURRENT_SIGNING_KEY="..."
    QSTASH_NEXT_SIGNING_KEY="..."
    
  • 在業(yè)務(wù)中觸發(fā)工作流節(jié)點(diǎn)
    import { Client } from "@upstash/workflow";
    
    export const workflow = new Client({ token: process.env.QSTASH_TOKEN! });   
    
    • 以“AI生成視頻標(biāo)題”這個(gè)功能為例,先創(chuàng)建一個(gè)trpc路由 generateTitle,在該路由中發(fā)起一個(gè)workflow,然后在workflow中處理業(yè)務(wù)邏輯
    // src/modules/videos/server/procedure.ts
    
    import { workflow } from '@/lib/workflow'
    
    export const videosRouter = createTRPCRouter({
      ...
      generateTitle: protectedProcedure
        .input(z.object({videoId: z.uuid()}))
        .mutation(async ({ ctx, input }) => {
          const { id: userId } = ctx.user
    
          const { workflowRunId } = await workflow.trigger({
            url: `${process.env.UPSTASH_WORKFLOW_URL}/api/videos/workflows/title`, // workflow的地址
            body: { userId, videoId: input.videoId }, 
          }) 
    
          return workflowRunId
        })
    })
    
    // src/app/api/videos/workflows/title/route.ts
    
    import { serve } from "@upstash/workflow/nextjs"
    
    import { db } from '@/db'
    import { videos } from '@/db/schema'
    import { and, eq } from 'drizzle-orm'
    
    interface InputType {
      userId: string,
      videoId: string
    }
    
    export const { POST } = serve(
      async (context) => {
        const input = context.requestPayload as InputType
        const { userId, videoId } = input
    
        const video = await context.run('get-video', async () => {...})
        ...
      }
    )
    
  • 關(guān)于mux
    • muxPlaybackId: 公開給前端使用的ID,可用于播放視頻、視頻預(yù)覽、封面圖,是在視頻資產(chǎn)Assets準(zhǔn)備就緒 video.asset.ready 時(shí)生成的,mux自動(dòng)生成的
    • muxTrackId: Asset里某一個(gè)視頻媒體軌道的ID,比如視頻軌道、音頻軌道、文本字幕軌道
    • generated_subtitles 表示在Mux完成視頻轉(zhuǎn)碼后,會(huì)自動(dòng)生成一條字幕軌道Subtitle Track,語言是en,名字叫English,字幕軌道生成完成時(shí),發(fā)送對(duì)應(yīng)的Webhook,也就是 video.asset.track.ready 事件
    // src/modules/videos/server/procedure.ts
    
    export const videosRouter = createTRPCRouter({
      create: protectedProcedure
        .mutation(async ({ ctx }) => {
           const { id: userId } = ctx.user
        
           const upload = await mux.video.uploads.create({
             new_asset_settings: {
                passthrough: userId, // 傳遞用戶ID到Mux
                playback_policy: ['public'], // 設(shè)置播放策略為公開
                input: [
                  {
                    generated_subtitles: [
                      {
                        language_code: 'en',
                        name: 'English'
                      }
                    ]
                  }
                ]
             }
             cors_origin: '*', // 允許所有CORS來源
           })
           ...
        })
    })
    
  • fetch 請(qǐng)求
    • Node.js 18+內(nèi)置的api,發(fā)起HTTP請(qǐng)求,向遠(yuǎn)程服務(wù)器獲取數(shù)據(jù)或發(fā)送數(shù)據(jù)
    • 基本語法:response.text() 讀取返回的純文本
    const response = await fetch(url, {
      method: 'GET' | 'POST' | 'PUT' | 'DELETE',
      headers: { ... },
      body: JSON.stringify(data)
    })
    
    const json = await response.json() // 解析響應(yīng)體
    
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容