From 9a39ae40ecc2a7004aeaa1b475c17c0b79eaf2d2 Mon Sep 17 00:00:00 2001 From: zhaohappy <2281756061@qq.com> Date: Wed, 12 Feb 2025 14:50:41 +0800 Subject: [PATCH] =?UTF-8?q?feat(avformat):=20mp4=20=E5=B0=81=E8=A3=85?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E8=AE=BE=E7=BD=AE=20matrix=20=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=EF=BC=8Cmse=20=E6=92=AD=E6=94=BE=E6=94=AF=E6=8C=81=20?= =?UTF-8?q?matrix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/avformat/formats/mov/writing/tkhd.ts | 9 +++++++-- src/avplayer/AVPlayer.ts | 14 +++++++++++--- src/avplayer/mse/MSEPipeline.ts | 13 +++++++++++-- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/src/avformat/formats/mov/writing/tkhd.ts b/src/avformat/formats/mov/writing/tkhd.ts index 21c0fea6..035e84e8 100644 --- a/src/avformat/formats/mov/writing/tkhd.ts +++ b/src/avformat/formats/mov/writing/tkhd.ts @@ -117,8 +117,13 @@ export default function write(ioWriter: IOWriter, stream: Stream, movContext: MO // reserved ioWriter.writeInt16(0) - - writeMatrix(ioWriter, 1, 0, 0, 1, 0, 0) + const matrix = stream.metadata[AVStreamMetadataKey.MATRIX] + if (matrix) { + writeMatrix(ioWriter, matrix[0], matrix[1], matrix[3], matrix[4], matrix[6], matrix[7]) + } + else { + writeMatrix(ioWriter, 1, 0, 0, 1, 0, 0) + } ioWriter.writeUint32(width) ioWriter.writeUint32(height) diff --git a/src/avplayer/AVPlayer.ts b/src/avplayer/AVPlayer.ts index f63eb4b1..7004d955 100644 --- a/src/avplayer/AVPlayer.ts +++ b/src/avplayer/AVPlayer.ts @@ -1583,7 +1583,8 @@ export default class AVPlayer extends Emitter implements ControllerObserver { serializeAVCodecParameters(videoStream.codecpar), videoStream.timeBase, videoStream.startTime, - this.demuxer2VideoDecoderChannel.port2 + this.demuxer2VideoDecoderChannel.port2, + videoStream.metadata[AVStreamMetadataKey.MATRIX] ) } if (audioStream && options.audio) { @@ -1766,7 +1767,7 @@ export default class AVPlayer extends Emitter implements ControllerObserver { : this.canvas // 处理旋转 - if (videoStream.metadata[AVStreamMetadataKey.MATRIX]) { + if (videoStream.metadata[AVStreamMetadataKey.MATRIX] && !this.useMSE) { this.renderRotate = -(Math.atan2(videoStream.metadata[AVStreamMetadataKey.MATRIX][3], videoStream.metadata[AVStreamMetadataKey.MATRIX][0]) * (180 / Math.PI)) } @@ -2971,7 +2972,14 @@ export default class AVPlayer extends Emitter implements ControllerObserver { await this.doSeek(this.currentTime, stream.index, { onBeforeSeek: async () => { await AVPlayer.DemuxerThread.changeConnectStream(this.taskId, stream.index, this.selectedVideoStream.index) - await AVPlayer.MSEThread.reAddStream(this.taskId, stream.index, serializeAVCodecParameters(stream.codecpar), stream.timeBase, stream.startTime) + await AVPlayer.MSEThread.reAddStream( + this.taskId, + stream.index, + serializeAVCodecParameters(stream.codecpar), + stream.timeBase, + stream.startTime, + stream.metadata[AVStreamMetadataKey.MATRIX] + ) } }) } diff --git a/src/avplayer/mse/MSEPipeline.ts b/src/avplayer/mse/MSEPipeline.ts index c4d7f606..cf31d9bb 100644 --- a/src/avplayer/mse/MSEPipeline.ts +++ b/src/avplayer/mse/MSEPipeline.ts @@ -69,6 +69,7 @@ import isPointer from 'cheap/std/function/isPointer' import * as is from 'common/util/is' import os from 'common/util/os' import { MPEG4AudioObjectTypes } from 'avutil/codecs/aac' +import { AVStreamMetadataKey } from 'avutil/AVStream' export interface MSETaskOptions extends TaskOptions { isLive: boolean @@ -912,7 +913,8 @@ export default class MSEPipeline extends Pipeline { parameters: pointer | AVCodecParametersSerialize, timeBase: Rational, startPTS: int64, - pullIPCPort: MessagePort + pullIPCPort: MessagePort, + matrix?: number[] ) { const task = this.tasks.get(taskId) if (task) { @@ -951,6 +953,9 @@ export default class MSEPipeline extends Pipeline { if (codecpar.codecId === AVCodecID.AV_CODEC_ID_MP3) { stream.codecpar.codecTag = mktag('.mp3') } + if (matrix) { + stream.metadata[AVStreamMetadataKey.MATRIX] = matrix + } const useSampleRateTimeBase = codecpar.codecType === AVMediaType.AVMEDIA_TYPE_AUDIO && codecpar.frameSize @@ -1046,7 +1051,8 @@ export default class MSEPipeline extends Pipeline { streamIndex: int32, parameters: pointer | AVCodecParametersSerialize, timeBase: Rational, - startPTS: int64 + startPTS: int64, + matrix?: number[] ) { const task = this.tasks.get(taskId) if (task) { @@ -1095,6 +1101,9 @@ export default class MSEPipeline extends Pipeline { if (codecpar.codecId === AVCodecID.AV_CODEC_ID_MP3) { stream.codecpar.codecTag = mktag('.mp3') } + if (matrix) { + stream.metadata[AVStreamMetadataKey.MATRIX] = matrix + } const useSampleRateTimeBase = codecpar.codecType === AVMediaType.AVMEDIA_TYPE_AUDIO && codecpar.frameSize