You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Node.js获取视频宽高 可结合Puppeteer操作DOM实现

可行实现方案

你已经有Puppeteer的DOM操作权限,优先选用浏览器侧直接读取的方案,实现成本低、准确率高,以下是按优先级排序的可选方案:

  • 方案1:直接读取当前页面已有video元素的原始尺寸
    你在页面内找到的video元素本身就携带了视频原始宽高属性,直接读取videoWidth和videoHeight即可,注意不要和元素样式上的width/height混淆,后者是渲染尺寸,不是视频本身的分辨率。
    唯一注意项:需要等视频元数据加载完成后再读取,否则会拿到0值,你可以在$$eval逻辑里加入元数据加载等待逻辑,或者优先用元数据已加载的元素数据。
  • 方案2:动态创建video元素加载目标URL获取尺寸
    如果原页面的video元素还未加载元数据,或者你仅拿到视频URL需要单独校验,可直接在Puppeteer的页面上下文内创建一个隐藏的video元素,主动加载视频元数据后读取宽高,该方案不受原页面加载状态影响,准确率更高。
  • 方案3:服务端直接解析视频元数据
    如果你后续脱离Puppeteer环境仅保留视频URL,可引入fluent-ffmpeg库的ffprobe能力,仅拉取视频文件头解析元数据,不需要下载完整视频,适合批量处理场景。

优化后代码示例

你可以直接修改原有$$eval部分的逻辑,同时返回视频URL和对应宽高:

export async function _getSourcesLinks(targetUrl: string): Promise<{src: string, width: number, height: number}[]> {
  return await puppeteer.launch({
    args: ['--no-sandbox', '--disable-setuid-sandbox'],
    headless: true,
  }).then(async browser => {
    try {
      const page = await browser.newPage()
      page.setJavaScriptEnabled(true)

      await page.goto(targetUrl, {
        waitUntil: 'load'
      })

      try {
        await page.waitForTimeout(1500)
      } catch (error) {
        console.error(error)
      }

      const videoInfos = await page.$$eval<Element>('video, .video, [src]', async (videos) => {
        const result = []
        for (const video of videos) {
          const src = video.getAttribute('src')
          if (!src) continue
          // 优先读取现有元素的宽高
          let width = (video as HTMLVideoElement).videoWidth || 0
          let height = (video as HTMLVideoElement).videoHeight || 0
          // 如果拿不到则动态创建元素加载元数据
          if (width === 0 || height === 0) {
            const tempVideo = document.createElement('video')
            tempVideo.src = src
            // 等待元数据加载
            await new Promise((resolve) => {
              tempVideo.addEventListener('loadedmetadata', resolve, { once: true })
              // 超时兜底,避免无限制等待
              setTimeout(resolve, 3000)
            })
            width = tempVideo.videoWidth
            height = tempVideo.videoHeight
          }
          result.push({ src, width, height })
        }
        return result
      })

      const downloadTargets = videoInfos.filter(info => {
        console.log(info.src)
        const fitPattern = /.*\.mp4.*/
        return fitPattern.test(info.src)
      })

      browser.close()
      return downloadTargets

    } catch (error) {
      console.error(error)
      return []
    }
  })
}

内容的提问来源于stack exchange,提问作者Aviv Ben Shahar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 14:24:01