import RTSPClient from "../RTSPClient" ; import { RTPPacket , BitStream } from "../util" ; import * as transform from "sdp-transform" ; import { Writable } from "stream" ; interface Details { codec : string ; mediaSource : transform . MediaDescription ; rtpChannel : number ; rtcpChannel : number ; } export default class AACTransport { client : RTSPClient ; stream : Writable ; ObjectType = 0 ; FrequencyIndex = 0 ; ChannelConfiguration = 0 ; constructor ( client , stream , details ) { this . client = client ; this . stream = stream ; client . on ( "data" , ( channel , data , packet ) => { if ( channel == details . rtpChannel ) { this . processRTPPacket ( packet ) ; } } ) ; let fmtp = details . mediaSource . fmtp [ 0 ] ; const fmtpConfig = transform . parseParams ( fmtp . config ) ; let bs = new BitStream ( ) ; bs . AddHexString ( fmtpConfig [ "config" ] . toString ( ) ) ; /***
        5 bits: object type
            if (object type == 31)
            6 bits + 32: object type
        4 bits: frequency index
            if (frequency index == 15)
            24 bits: frequency
        4 bits: channel configuration
        var bits: AOT Specific Config
        ***/ this . ObjectType = bs . Read ( 5 ) ; this . FrequencyIndex = bs . Read ( 4 ) ; this . ChannelConfiguration = bs . Read ( 4 ) ; } processRTPPacket ( packet ) { let rtp_payload = packet . payload ; let ptr = 0 ; let audio_data = [ ] ; while ( true ) { if ( ptr + 4 > rtp_payload . length ) break ; let au_headers_length_bits = ( rtp_payload [ ptr ] << 8 ) + ( rtp_payload [ ptr + 1 ] << 0 ) ; let au_headers_length = Math . ceil ( au_headers_length_bits / 8.0 ) ; ptr += 2 ; let aac_frame_size = ( ( rtp_payload [ ptr ] << 8 ) + ( rtp_payload [ ptr + 1 ] << 0 ) ) >> 3 ; let aac_index_delta = rtp_payload [ ptr + 1 ] & 0x03 ; ptr += au_headers_length ; if ( ptr + aac_frame_size > rtp_payload . length ) break ; audio_data . push ( rtp_payload . slice ( ptr , ptr + aac_frame_size ) ) ; ptr += aac_frame_size ; } for ( let x = 0 ; x < audio_data . length ; x ++ ) { let data = audio_data [ x ] ; let bs = new BitStream ( ) ; bs . AddValue ( 0xfff , 12 ) ; bs . AddValue ( 0 , 1 ) ; bs . AddValue ( 0 , 2 ) ; let protection_absent = 1 ; bs . AddValue ( protection_absent , 1 ) ; bs . AddValue ( this . ObjectType - 1 , 2 ) ; bs . AddValue ( this . FrequencyIndex , 4 ) ; bs . AddValue ( 0 , 1 ) ; bs . AddValue ( this . ChannelConfiguration , 3 ) ; bs . AddValue ( 0 , 1 ) ; bs . AddValue ( 0 , 1 ) ; bs . AddValue ( 0 , 1 ) ; bs . AddValue ( 0 , 1 ) ; bs . AddValue ( data . length + 7 , 13 ) ; bs . AddValue ( 2047 , 11 ) ; let num_acc_frames = 1 ; bs . AddValue ( num_acc_frames - 1 , 1 ) ; if ( protection_absent == 0 ) bs . AddValue ( 0xabcd , 16 ) ; let header = bs . ToArray ( ) ; this . stream . write ( header ) ; this . stream . write ( data ) ; } } }