@@ -4,6 +4,7 @@ import { file, tmpfile, write } from 'opfs-tools';
44import { audioResample , extractPCM4AudioData , sleep } from '../av-utils' ;
55import {
66extractFileConfig ,
7+ parseMatrix ,
78quickParseMP4File ,
89} from '../mp4-utils/mp4box-utils' ;
910import { DEFAULT_AUDIO_CONF , IClip } from './iclip' ;
@@ -85,6 +86,7 @@ export class MP4Clip implements IClip {
8586
8687 #localFile:OPFSToolFile ;
8788
89+ /** 存储视频头(box: ftyp, moov)的二进制数据 */
8890 #headerBoxPos:Array < { start :number ; size :number } > = [ ] ;
8991/**
9092 * 提供视频头(box: ftyp, moov)的二进制数据
@@ -103,6 +105,17 @@ export class MP4Clip implements IClip {
103105) . arrayBuffer ( ) ;
104106}
105107
108+ /**存储视频平移旋转信息,目前只还原旋转 */
109+ #parsedMatrix= {
110+ perspective :1 ,
111+ rotationDeg :0 ,
112+ rotationRad :0 ,
113+ scaleX :1 ,
114+ scaleY :1 ,
115+ translateX :0 ,
116+ translateY :0 ,
117+ } ;
118+
106119 #volume= 1 ;
107120
108121 #videoSamples:ExtMP4Sample [ ] = [ ] ;
@@ -160,11 +173,18 @@ export class MP4Clip implements IClip {
160173 ?mp4FileToSamples ( source , this . #opts)
161174 :Promise . resolve ( source )
162175) . then (
163- async ( { videoSamples, audioSamples, decoderConf, headerBoxPos} ) => {
176+ async ( {
177+ videoSamples,
178+ audioSamples,
179+ decoderConf,
180+ headerBoxPos,
181+ parsedMatrix,
182+ } ) => {
164183this . #videoSamples= videoSamples ;
165184this . #audioSamples= audioSamples ;
166185this . #decoderConf= decoderConf ;
167186this . #headerBoxPos= headerBoxPos ;
187+ this . #parsedMatrix= parsedMatrix ;
168188
169189const { videoFrameFinder, audioFrameFinder} = genDecoder (
170190{
@@ -355,6 +375,7 @@ export class MP4Clip implements IClip {
355375audioSamples :preAudioSlice ?? [ ] ,
356376decoderConf :this . #decoderConf,
357377headerBoxPos :this . #headerBoxPos,
378+ parsedMatrix :this . #parsedMatrix,
358379} ,
359380this . #opts,
360381) ;
@@ -365,6 +386,7 @@ export class MP4Clip implements IClip {
365386audioSamples :postAudioSlice ?? [ ] ,
366387decoderConf :this . #decoderConf,
367388headerBoxPos :this . #headerBoxPos,
389+ parsedMatrix :this . #parsedMatrix,
368390} ,
369391this . #opts,
370392) ;
@@ -382,6 +404,7 @@ export class MP4Clip implements IClip {
382404audioSamples :[ ...this . #audioSamples] ,
383405decoderConf :this . #decoderConf,
384406headerBoxPos :this . #headerBoxPos,
407+ parsedMatrix :this . #parsedMatrix,
385408} ,
386409this . #opts,
387410) ;
@@ -408,6 +431,7 @@ export class MP4Clip implements IClip {
408431audio :null ,
409432} ,
410433headerBoxPos :this . #headerBoxPos,
434+ parsedMatrix :this . #parsedMatrix,
411435} ,
412436this . #opts,
413437) ;
@@ -426,6 +450,7 @@ export class MP4Clip implements IClip {
426450video :null ,
427451} ,
428452headerBoxPos :this . #headerBoxPos,
453+ parsedMatrix :this . #parsedMatrix,
429454} ,
430455this . #opts,
431456) ;
@@ -524,6 +549,15 @@ async function mp4FileToSamples(otFile: OPFSToolFile, opts: IMP4ClipOpts = {}) {
524549let videoSamples :ExtMP4Sample [ ] = [ ] ;
525550let audioSamples :ExtMP4Sample [ ] = [ ] ;
526551let headerBoxPos :Array < { start :number ; size :number } > = [ ] ;
552+ const parsedMatrix = {
553+ perspective :1 ,
554+ rotationDeg :0 ,
555+ rotationRad :0 ,
556+ scaleX :1 ,
557+ scaleY :1 ,
558+ translateX :0 ,
559+ translateY :0 ,
560+ } ;
527561
528562let videoDeltaTS = - 1 ;
529563let audioDeltaTS = - 1 ;
@@ -537,6 +571,8 @@ async function mp4FileToSamples(otFile: OPFSToolFile, opts: IMP4ClipOpts = {}) {
537571const moov = data . mp4boxFile . moov ! ;
538572headerBoxPos . push ( { start :moov . start , size :moov . size } ) ;
539573
574+ Object . assign ( parsedMatrix , parseMatrix ( moov . mvhd . matrix ) ) ;
575+
540576let { videoDecoderConf :vc , audioDecoderConf :ac } = extractFileConfig (
541577data . mp4boxFile ,
542578data . info ,
@@ -599,6 +635,7 @@ async function mp4FileToSamples(otFile: OPFSToolFile, opts: IMP4ClipOpts = {}) {
599635 audioSamples,
600636 decoderConf,
601637 headerBoxPos,
638+ parsedMatrix,
602639} ;
603640}
604641