import { Tube } from '../component' ; import { Transform } from 'stream' ; import { MessageType , Message } from '../message' ; import { VideoMedia } from '../../utils/protocols/sdp' ; import { marker , payloadType } from '../../utils/protocols/rtp' ; import { H264DepayParser , NAL_TYPES } from './parser' ; export class H264Depay extends Tube { constructor ( ) { let h264PayloadType ; let idrFound = false ; let packets = [ ] ; const h264DepayParser = new H264DepayParser ( ) ; const incoming = new Transform ( { objectMode : true , transform : function ( msg , _encoding , callback ) { if ( msg . type === MessageType . SDP ) { const h264Media = msg . sdp . media . find ( ( media ) : media is VideoMedia => { return ( media . type === 'video' && media . rtpmap !== undefined && media . rtpmap . encodingName === 'H264' ) ; } ) ; if ( h264Media !== undefined && h264Media . rtpmap !== undefined ) { h264PayloadType = h264Media . rtpmap . payloadType ; } callback ( undefined , msg ) ; } else if ( msg . type === MessageType . RTP && payloadType ( msg . data ) === h264PayloadType ) { const endOfFrame = marker ( msg . data ) ; const h264Message = h264DepayParser . parse ( msg ) ; if ( h264Message === null || ( ! idrFound && h264Message . nalType !== NAL_TYPES . IDR_PICTURE ) ) { callback ( ) ; return ; } idrFound = true ; packets . push ( h264Message . data ) ; if ( endOfFrame ) { this . push ( { ... h264Message , data : packets . length === 1 ? packets [ 0 ] : Buffer . concat ( packets ) , } ) ; packets = [ ] ; } callback ( ) ; } else { callback ( undefined , msg ) ; } } , } ) ; super ( incoming ) ; } }