Skip to content

Commit

Permalink
feat(avformat): AVStream 的 metadata key 使用枚举
Browse files Browse the repository at this point in the history
  • Loading branch information
zhaohappy committed Feb 6, 2025
1 parent f27f1c9 commit 24b7023
Show file tree
Hide file tree
Showing 22 changed files with 307 additions and 72 deletions.
8 changes: 5 additions & 3 deletions src/avformat/formats/IFlacFormat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ import { AV_MILLI_TIME_BASE_Q, NOPTS_VALUE_BIGINT } from 'avutil/constant'
import seekInBytes from '../function/seekInBytes'
import * as array from 'common/util/array'
import { avRescaleQ } from 'avutil/util/rational'
import { AVStreamMetadataKey } from 'avutil/stringEnum'
import { parseVorbisComment } from './ogg/vorbis'

const PACKET_SIZE = 1024

Expand Down Expand Up @@ -188,13 +190,13 @@ export default class IFlacFormat extends IFormat {
const vendorStringLength = await formatContext.ioReader.readUint32()
const vendorString = await formatContext.ioReader.readString(vendorStringLength)
const userCommentListLength = await formatContext.ioReader.readUint32()
const comments = []
const comments: string[] = []
for (let i = 0; i < userCommentListLength; i++) {
const length = await formatContext.ioReader.readUint32()
comments.push(await formatContext.ioReader.readString(length))
}
stream.metadata['vendor'] = vendorString
stream.metadata['comments'] = comments
stream.metadata[AVStreamMetadataKey.VENDOR] = vendorString
parseVorbisComment(comments, stream.metadata)
formatContext.ioReader.setEndian(true)
}
else if (blockType === MetaDataBlockType.CUESHEET) {
Expand Down
5 changes: 3 additions & 2 deletions src/avformat/formats/IMatroskaFormat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ import concatTypeArray from 'common/function/concatTypeArray'
import * as text from 'common/util/text'
import isDef from 'common/function/isDef'
import * as naluUtil from 'avutil/util/nalu'
import { AVStreamMetadataKey } from 'avutil/stringEnum'

export default class IMatroskaFormat extends IFormat {

Expand Down Expand Up @@ -148,10 +149,10 @@ export default class IMatroskaFormat extends IFormat {
}

if (track.language) {
stream.metadata['language'] = track.language
stream.metadata[AVStreamMetadataKey.LANGUAGE] = track.language
}
if (track.name) {
stream.metadata['name'] = track.name
stream.metadata[AVStreamMetadataKey.TITLE] = track.name
}

if (track.audio) {
Expand Down
14 changes: 4 additions & 10 deletions src/avformat/formats/IOggFormat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ import { OggPage, OggsCommentPage, PagePayload } from './ogg/OggPage'
import { AVCodecID, AVMediaType } from 'avutil/codec'
import * as logger from 'common/util/logger'
import { OpusOggsIdPage, OpusOggsCommentPage } from './ogg/opus'
import { VorbisOggsIdPage, VorbisOggsCommentPage } from './ogg/vorbis'
import { VorbisOggsIdPage, VorbisOggsCommentPage, parseVorbisComment } from './ogg/vorbis'
import * as errorType from 'avutil/error'
import concatTypeArray from 'common/function/concatTypeArray'
import IFormat from './IFormat'
Expand All @@ -47,6 +47,7 @@ import { avRescaleQ } from 'avutil/util/rational'
import * as array from 'common/util/array'
import SafeUint8Array from 'cheap/std/buffer/SafeUint8Array'
import * as bigint from 'common/util/bigint'
import { AVStreamMetadataKey } from 'avutil/stringEnum'

interface IOggFormatPrivateData {
serialNumber: number
Expand Down Expand Up @@ -166,16 +167,9 @@ export default class IOggFormat extends IFormat {

private addComment(comments: OggsCommentPage, stream: AVStream) {
if (comments.vendorString) {
stream.metadata['vendor'] = comments.vendorString
stream.metadata[AVStreamMetadataKey.VENDOR] = comments.vendorString
}
array.each(comments.comments.list, (comment) => {
const item = comment.split('=')
if (item.length > 1) {
const key = item.shift()
const value = item.join('=')
stream.metadata[key] = value
}
})
parseVorbisComment(comments.comments.list, stream.metadata)
}

private async createStream(formatContext: AVIFormatContext, payload: Uint8Array) {
Expand Down
5 changes: 3 additions & 2 deletions src/avformat/formats/IWebVttFormat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import * as array from 'common/util/array'
import * as text from 'common/util/text'
import { hhColonDDColonSSDotMill2Int64 } from 'common/util/time'
import { NOPTS_VALUE_BIGINT } from 'avutil/constant'
import { AVStreamMetadataKey } from 'avutil/stringEnum'


export default class IWebVttFormat extends IFormat {
Expand Down Expand Up @@ -98,7 +99,7 @@ export default class IWebVttFormat extends IFormat {

const header = await formatContext.ioReader.readLine()
if (header.indexOf('-') > 0) {
stream.metadata['title'] = header.split('-').pop().trim()
stream.metadata[AVStreamMetadataKey.TITLE] = header.split('-').pop().trim()
}

this.index = 0
Expand Down Expand Up @@ -189,7 +190,7 @@ export default class IWebVttFormat extends IFormat {
}
catch (error) {

stream.metadata['styles'] = styles
stream.metadata[AVStreamMetadataKey.STYLES] = styles

return 0
}
Expand Down
15 changes: 8 additions & 7 deletions src/avformat/formats/OMatroskaFormat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import * as hevc from 'avutil/codecs/hevc'
import * as vvc from 'avutil/codecs/vvc'
import * as intread from 'avutil/util/intread'
import { Uint8ArrayInterface } from 'common/io/interface'
import { AVStreamMetadataKey } from 'avutil/stringEnum'

export interface OMatroskaFormatOptions {
isLive?: boolean
Expand Down Expand Up @@ -214,14 +215,14 @@ export default class OMatroskaFormat extends OFormat {
crypto.random(this.random)
context.attachments.entry.push({
uid: this.randomView.getBigUint64(0),
name: stream.metadata['name'] || 'unknown',
mime: stream.metadata['mime'] || 'unknown',
name: stream.metadata[AVStreamMetadataKey.TITLE] || 'unknown',
mime: stream.metadata[AVStreamMetadataKey.MIME] || 'unknown',
data: {
data: mapUint8Array(stream.codecpar.extradata, reinterpret_cast<size>(stream.codecpar.extradataSize)),
size: static_cast<int64>(stream.codecpar.extradataSize),
pos: -1n
},
description: stream.metadata['description'] || 'unknown'
description: stream.metadata[AVStreamMetadataKey.DESCRIPTION] || 'unknown'
})
}
else {
Expand All @@ -237,11 +238,11 @@ export default class OMatroskaFormat extends OFormat {
size: static_cast<int64>(stream.codecpar.extradataSize)
}
}
if (stream.metadata['language']) {
track.language = stream.metadata['language']
if (stream.metadata[AVStreamMetadataKey.LANGUAGE]) {
track.language = stream.metadata[AVStreamMetadataKey.LANGUAGE]
}
if (stream.metadata['name']) {
track.name = stream.metadata['name']
if (stream.metadata[AVStreamMetadataKey.TITLE]) {
track.name = stream.metadata[AVStreamMetadataKey.TITLE]
}

switch (stream.codecpar.codecType) {
Expand Down
25 changes: 13 additions & 12 deletions src/avformat/formats/OMp3Format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ import * as id3v2 from './mp3/id3v2'
import { mapUint8Array } from 'cheap/std/memory'
import * as text from 'common/util/text'
import * as object from 'common/util/object'
import { AVStreamMetadataKey } from 'avutil/stringEnum'

const XING_NUM_BAGS = 400

Expand Down Expand Up @@ -247,10 +248,10 @@ export default class OMp3Format extends OFormat {
// we write it, because some (broken) tools always expect it to be present
this.xingWriter.writeUint32(0)

const metadata = stream.metadata as Mp3MetaData
const metadata = stream.metadata as Mp3MetaData || {}

if (metadata?.encoder) {
const buffer = text.encode(metadata.encoder)
if (metadata[AVStreamMetadataKey.ENCODER]) {
const buffer = text.encode(metadata[AVStreamMetadataKey.ENCODER])
this.xingWriter.writeBuffer(buffer.subarray(0, 9))
}
else {
Expand Down Expand Up @@ -412,7 +413,7 @@ export default class OMp3Format extends OFormat {
return stream.codecpar.codecId === AVCodecID.AV_CODEC_ID_MP3
})

const metadata = stream.metadata as Mp3MetaData
const metadata = stream.metadata as Mp3MetaData || {}

const id1Buffer = new Uint8Array(ID3V1_SIZE)
const id1Writer = new BufferWriter(id1Buffer)
Expand All @@ -426,28 +427,28 @@ export default class OMp3Format extends OFormat {
}
}

if (metadata.title) {
writeText(metadata.title)
if (metadata[AVStreamMetadataKey.TITLE]) {
writeText(metadata[AVStreamMetadataKey.TITLE])
}
else {
id1Writer.skip(30)
}
if (metadata.artist) {
writeText(metadata.artist)
if (metadata[AVStreamMetadataKey.ARTIST]) {
writeText(metadata[AVStreamMetadataKey.ARTIST])
}
else {
id1Writer.skip(30)
}
if (metadata.album) {
writeText(metadata.album)
if (metadata[AVStreamMetadataKey.ALBUM]) {
writeText(metadata[AVStreamMetadataKey.ALBUM])
}
else {
id1Writer.skip(30)
}

id1Buffer[127] = 0xff
if (metadata.genre) {
id1Buffer[127] = +metadata.genre
if (metadata[AVStreamMetadataKey.GENRE]) {
id1Buffer[127] = +metadata[AVStreamMetadataKey.GENRE]
}

formatContext.ioWriter.writeBuffer(id1Buffer)
Expand Down
19 changes: 18 additions & 1 deletion src/avformat/formats/OOggFormat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import * as logger from 'common/util/logger'
import { getAVPacketData } from 'avutil/util/avpacket'
import { NOPTS_VALUE_BIGINT } from 'avutil/constant'
import { OpusOggsCommentPage, OpusOggsIdPage } from './ogg/opus'
import { VorbisOggsCommentPage, VorbisOggsIdPage } from './ogg/vorbis'
import { addVorbisComment, VorbisOggsCommentPage, VorbisOggsIdPage } from './ogg/vorbis'
import { mapUint8Array } from 'cheap/std/memory'
import IOReaderSync from 'common/io/IOReaderSync'
import * as errorType from 'avutil/error'
Expand Down Expand Up @@ -178,6 +178,10 @@ export default class OOggFormat extends OFormat {
const idPage = new OpusOggsIdPage()
const commentPage = new OpusOggsCommentPage()
idPage.streamIndex = stream.index
const list = addVorbisComment(stream.metadata)
list.forEach((value) => {
commentPage.addComment(value)
})
idPage.setCodec(stream.codecpar)
commentPage.streamIndex = stream.index
this.headerPagesPayload = [
Expand All @@ -197,6 +201,11 @@ export default class OOggFormat extends OFormat {
idPage.streamIndex = stream.index
commentPage.streamIndex = stream.index

const list = addVorbisComment(stream.metadata)
list.forEach((value) => {
commentPage.addComment(value)
})

this.cacheWriter.reset()
idPage.write(this.cacheWriter)
this.writePage(stream, formatContext.ioWriter, this.cacheWriter.getBuffer().slice(), 2)
Expand Down Expand Up @@ -264,6 +273,10 @@ export default class OOggFormat extends OFormat {

const commentPage = new OggsCommentPage()
commentPage.streamIndex = stream.index
const list = addVorbisComment(stream.metadata)
list.forEach((value) => {
commentPage.addComment(value)
})

this.cacheWriter.setEndian(true)
this.cacheWriter.reset()
Expand All @@ -290,6 +303,10 @@ export default class OOggFormat extends OFormat {

const commentPage = new OggsCommentPage()
commentPage.streamIndex = stream.index
const list = addVorbisComment(stream.metadata)
list.forEach((value) => {
commentPage.addComment(value)
})
this.cacheWriter.reset()
commentPage.write(this.cacheWriter)
this.writePage(stream, formatContext.ioWriter, this.cacheWriter.getBuffer().slice(), 0)
Expand Down
7 changes: 4 additions & 3 deletions src/avformat/formats/mov/function/buildIndex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { AVMediaType } from 'avutil/codec'
import * as logger from 'common/util/logger'
import { avRescaleQ } from 'avutil/util/rational'
import { AV_MILLI_TIME_BASE_Q, NOPTS_VALUE_BIGINT } from 'avutil/constant'
import { AVStreamMetadataKey } from 'avutil/stringEnum'


export function buildIndex(stream: Stream, movContext: MOVContext) {
Expand Down Expand Up @@ -68,14 +69,14 @@ export function buildIndex(stream: Stream, movContext: MOVContext) {

const samplesIndex: Sample[] = []

if (!movContext.ignoreEditlist && stream.metadata.elst?.length) {
if (!movContext.ignoreEditlist && stream.metadata[AVStreamMetadataKey.ELST]?.length) {
let timeOffset = 0n
let editStartIndex = 0
let unsupported = false
let emptyDuration = 0n
let startTime = 0n
for (let i = 0; i < stream.metadata.elst.length; i++) {
const e = stream.metadata.elst[i]
for (let i = 0; i < stream.metadata[AVStreamMetadataKey.ELST].length; i++) {
const e = stream.metadata[AVStreamMetadataKey.ELST][i]
if (i === 0 && e.mediaTime === -1n) {
emptyDuration = e.segmentDuration
editStartIndex = 1
Expand Down
3 changes: 2 additions & 1 deletion src/avformat/formats/mov/parsing/elst.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import IOReader from 'common/io/IOReader'
import Stream from 'avutil/AVStream'
import { Atom, ElstEntry, MOVContext } from '../type'
import * as logger from 'common/util/logger'
import { AVStreamMetadataKey } from 'avutil/stringEnum'

export default async function read(ioReader: IOReader, stream: Stream, atom: Atom, movContext: MOVContext) {

Expand Down Expand Up @@ -64,7 +65,7 @@ export default async function read(ioReader: IOReader, stream: Stream, atom: Ato
})
}

stream.metadata.elst = entries
stream.metadata[AVStreamMetadataKey.ELST] = entries

const remainingLength = atom.size - Number(ioReader.getPos() - now)
if (remainingLength > 0) {
Expand Down
3 changes: 2 additions & 1 deletion src/avformat/formats/mov/parsing/hdlr.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { Atom, MOVContext } from '../type'
import * as logger from 'common/util/logger'
import isDef from 'common/function/isDef'
import { HandlerType2MediaType } from '../mov'
import { AVStreamMetadataKey } from 'avutil/stringEnum'

export default async function read(ioReader: IOReader, stream: Stream, atom: Atom, movContext: MOVContext) {
const now = ioReader.getPos()
Expand Down Expand Up @@ -63,7 +64,7 @@ export default async function read(ioReader: IOReader, stream: Stream, atom: Ato
if (skip) {
await ioReader.skip(1)
}
stream.metadata['handlerName'] = await ioReader.readString(len - (skip ? 1 : 0))
stream.metadata[AVStreamMetadataKey.HANDLER_NAME] = await ioReader.readString(len - (skip ? 1 : 0))
}
}

Expand Down
9 changes: 5 additions & 4 deletions src/avformat/formats/mov/parsing/mdhd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import IOReader from 'common/io/IOReader'
import Stream from 'avutil/AVStream'
import { Atom, MOVContext } from '../type'
import * as logger from 'common/util/logger'
import { AVStreamMetadataKey } from 'avutil/stringEnum'

export default async function read(ioReader: IOReader, stream: Stream, atom: Atom, movContext: MOVContext) {
const now = ioReader.getPos()
Expand Down Expand Up @@ -56,8 +57,8 @@ export default async function read(ioReader: IOReader, stream: Stream, atom: Ato
stream.duration = duration
stream.timeBase.den = timescale
stream.timeBase.num = 1
stream.metadata['creationTime'] = creationTime
stream.metadata['modificationTime'] = modificationTime
stream.metadata[AVStreamMetadataKey.CREATION_TIME] = creationTime
stream.metadata[AVStreamMetadataKey.MODIFICATION_TIME] = modificationTime


const language = await ioReader.readUint16()
Expand All @@ -68,8 +69,8 @@ export default async function read(ioReader: IOReader, stream: Stream, atom: Ato

const languageString = String.fromCharCode(chars[0] + 0x60, chars[1] + 0x60, chars[2] + 0x60)

stream.metadata['language'] = language
stream.metadata['languageString'] = languageString
stream.metadata[AVStreamMetadataKey.LANGUAGE] = language
stream.metadata[AVStreamMetadataKey.LANGUAGE_STRING] = languageString

await ioReader.skip(2)

Expand Down
7 changes: 4 additions & 3 deletions src/avformat/formats/mov/parsing/stsd.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ import colr from './colr'

import ac3 from './dac3'
import eac3 from './dec3'
import { AVStreamMetadataKey } from 'avutil/stringEnum'

export default async function read(ioReader: IOReader, stream: Stream, atom: Atom, movContext: MOVContext) {
const now = ioReader.getPos()
Expand Down Expand Up @@ -90,7 +91,7 @@ export default async function read(ioReader: IOReader, stream: Stream, atom: Ato
// revision level
await ioReader.skip(2)
// vendor
stream.metadata['vendorId'] = await ioReader.readString(4)
stream.metadata[AVStreamMetadataKey.VENDOR_ID] = await ioReader.readString(4)
// temporal quality
await ioReader.skip(4)
// spatial quality
Expand All @@ -114,7 +115,7 @@ export default async function read(ioReader: IOReader, stream: Stream, atom: Ato
if (len > 31) {
len = 31
}
stream.metadata['encoder'] = await ioReader.readString(len)
stream.metadata[AVStreamMetadataKey.ENCODER] = await ioReader.readString(len)
if (len < 31) {
await ioReader.skip(31 - len)
}
Expand Down Expand Up @@ -235,7 +236,7 @@ export default async function read(ioReader: IOReader, stream: Stream, atom: Ato
// Revision level
await ioReader.skip(2)

stream.metadata['vendorId'] = await ioReader.readString(4)
stream.metadata[AVStreamMetadataKey.VENDOR_ID] = await ioReader.readString(4)

stream.codecpar.chLayout.nbChannels = await ioReader.readUint16()
stream.codecpar.bitsPerCodedSample = await ioReader.readUint16()
Expand Down
Loading

0 comments on commit 24b7023

Please sign in to comment.