import { H264Media } from '../../../utils/protocols/sdp' ; import { base64DecToArr } from './utils' ; import { Box , Container } from './isom' ; import { SPSParser } from './spsparser' ; const PROFILE_NAMES = { 66 : 'Baseline' , 77 : 'Main' , 100 : 'High' , } ; const h264EncodingName = ( profileLevelId ) => { const profileCode = parseInt ( profileLevelId . substr ( 0 , 2 ) , 16 ) ; const levelCode = parseInt ( profileLevelId . substr ( 4 , 2 ) , 16 ) ; const profile = PROFILE_NAMES [ profileCode ] || profileCode . toString ( ) ; const level = ( levelCode / 10 ) . toFixed ( 1 ) ; return { coding : 'H.264' , profile , level , } ; } ; export const h264Settings = ( media , date , trackId ) => { const profileLevelId = media . fmtp . parameters [ 'profile-level-id' ] ; const parameterSets = media . fmtp . parameters [ 'sprop-parameter-sets' ] . split ( ',' ) . map ( base64DecToArr ) ; const sps = parameterSets . slice ( 0 , 1 ) ; const pps = parameterSets . slice ( 1 ) ; const parsedSps = new SPSParser ( sps [ 0 ] . buffer ) . parse ( ) ; const FALLBACK_FRAME_DURATION = 3600 ; return { mediaHeaderBox : new Box ( 'vmhd' ) , sampleEntryBox : new Container ( 'avc1' , { width : parsedSps . width , height : parsedSps . height , } , new Box ( 'avcC' , { AVCProfileIndication : sps [ 0 ] [ 1 ] , profile_compatibility : sps [ 0 ] [ 2 ] , AVCLevelIndication : sps [ 0 ] [ 3 ] , sequenceParameterSets : sps , pictureParameterSets : pps , } ) ) , tkhd : { track_ID : trackId , creation_time : date , modification_time : date , width : parsedSps . width << 16 , height : parsedSps . height << 16 , volume : 0 , } , hdlr : { } , mdhd : { timescale : media . rtpmap . clockrate , creation_time : date , modification_time : date , duration : 0 , } , defaultFrameDuration : media . framerate !== undefined && media . framerate > 0 ? Number ( media . rtpmap . clockrate ) / Number ( media . framerate ) || FALLBACK_FRAME_DURATION : FALLBACK_FRAME_DURATION , mime : `avc1.${ profileLevelId }` , codec : h264EncodingName ( profileLevelId ) , } ; } ;