惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
博客园_首页
博客园 - 司徒正美
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
C
Check Point Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Hugging Face - Blog
Hugging Face - Blog
B
Blog RSS Feed
阮一峰的网络日志
阮一峰的网络日志
D
DataBreaches.Net
The GitHub Blog
The GitHub Blog
G
Google Developers Blog
L
LangChain Blog
T
The Blog of Author Tim Ferriss
博客园 - 【当耐特】
Engineering at Meta
Engineering at Meta
Google DeepMind News
Google DeepMind News
雷峰网
雷峰网
量子位
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
I
InfoQ

WishMeLz

VOXI 使用记录 · WishMeLz MailHub · WishMeLz Docker 客户端中文 · WishMeLz SuJian 1.0:给自己的博客换一张素笺 · WishMeLz MailHub - 服务条款 · WishMeLz MailHub - 隐私权政策 · WishMeLz blog.itsse.cn blog.itsse.cn 柯尼卡美能达 bizhub C226 复印机 SMB 扫描到电脑配置教程 minio 最后的绝唱 搭建配置流程 - WishMeLz Namecrane/CraneMail 优化访问速度之 - Nginx stream 做 TCP 邮件代理 Scriptable 小组件 - 搬瓦工 - WishMeLz 港卡,CSL 记录 - WishMeLz Electron 主进程起一个可用的 HTTPS 静态服务器 - WishMeLz 目标域名在线测试 - WishMeLz 某x面板每月自动重置流量功能 - WishMeLz Safari 解锁 120hz - WishMeLz CraneMail 优化访问速度之 - Stunnel/HAProxy - WishMeLz Linux 工具箱整理 - WishMeLz Docker 使用指南 - WishMeLz
前端分片解析 MP4 视频编码,判断是否为 H.265/HEVC · WishMeLz
Wish · 2026-09-16 · via WishMeLz
npm install mp4box@0.5.4
const MP4Box = require('mp4box')

const DEFAULT_CHUNK_SIZE = 1024 * 1024
const DEFAULT_MAX_READ_SIZE = 16 * 1024 * 1024

export interface VideoCodecParseOptions {
    chunkSize?: number
    maxReadSize?: number
}

/**
 * 分片解析 MP4 中的视频轨道编码,解析失败或未解析到编码时返回空数组。
 */
export function parseVideoCodecs(
    file: File,
    options: VideoCodecParseOptions = {},
): Promise<string[]> {
    const chunkSize = options.chunkSize || DEFAULT_CHUNK_SIZE
    const maxReadSize = options.maxReadSize || DEFAULT_MAX_READ_SIZE

    return new Promise(resolve => {
        const mp4File = MP4Box.createFile(false)
        let readSize = 0
        let settled = false

        const finish = (codecs: string[]) => {
            if (settled) {
                return
            }
            settled = true
            resolve(codecs)
        }

        mp4File.onReady = (info: any) => {
            const tracks = info.videoTracks ||
                (info.tracks || []).filter((track: any) => track.video)
            const codecs = tracks
                .map((track: any) => String(track.codec || '').toLowerCase())
                .filter(Boolean)
            finish(codecs)
        }
        mp4File.onError = () => {
            finish([])
        }

        const readChunk = (start: number) => {
            if (settled) {
                return
            }
            if (start >= file.size || readSize >= maxReadSize) {
                finish([])
                return
            }

            const end = Math.min(start + chunkSize, file.size)
            const reader = new FileReader()
            reader.onload = () => {
                const buffer: any = reader.result
                if (!buffer) {
                    finish([])
                    return
                }

                buffer.fileStart = start
                readSize += buffer.byteLength

                let nextStart
                try {
                    nextStart = mp4File.appendBuffer(buffer)
                } catch (error) {
                    finish([])
                    return
                }

                if (!settled) {
                    const offset = typeof nextStart === 'number' && nextStart > start
                        ? nextStart
                        : end
                    readChunk(offset)
                }
            }
            reader.onerror = () => {
                finish([])
            }
            reader.readAsArrayBuffer(file.slice(start, end))
        }

        readChunk(0)
    })
}

使用

const BLOCKED_VIDEO_CODECS = ['hvc1', 'hev1', 'hevc', 'h265', 'h.265']
const codecs = await parseVideoCodecs(file)
let isBlockedCodec = codecs.some(codec => {
                    return BLOCKED_VIDEO_CODECS.some(blockedCodec => {
                        return codec.startsWith(blockedCodec) || codec.includes(blockedCodec)
                    })
                })