RTMP学习笔记(八) flv拉流处理学习

74 阅读1分钟

欢迎关注公众号:冒泡的肥皂

image.png

1.效果图延时超过了10s

image.png

2.拉流

  1. 首先要回个头消息

  2. 需要首先发送"AVC sequence header(AVCDecoderConfigurationRecord)"和"AAC sequence header(aacAudioSpecificConfig)",这两项数据包含的是重要的编码信息,没有它们,解码器将无法解码。

FLV格式详解和打包H264、AAC方案

        //Video的编码格式AVC也就是常说的H264
	public boolean isH264KeyFrame() {
		return videoData.length > 1 && videoData[0] == 0x17;
	}
        
        //说明后面承载的数据是H264的序列头也就是编码器配置SPS PPS而不是裸数据Nalu
	public boolean isAVCDecoderConfigurationRecord() {
		return isH264KeyFrame() && videoData.length > 2 && videoData[1] == 0x00;
	}  
        
        
        public boolean isAACAudioSpecificConfig(){
		return audioData.length>1 && audioData[1]==0;
	}
        
        
        
        if(msg instanceof VideoMessage) {
	  VideoMessage vm=(VideoMessage)msg
	  //设置avc信息
          if (vm.isAVCDecoderConfigurationRecord()) {
		log.info("avcDecoderConfigurationRecord  ok");
		avcDecoderConfigurationRecord = vm;
	  }
	}
        
        
        if(msg instanceof AudioMessage) {
	  AudioMessage am=(AudioMessage) msg;
          //acc
	  if (am.isAACAudioSpecificConfig()) {
	      aacAudioSpecificConfig = am;
	 }
	}
        
  1. 内容

encodeMediaAsFlvTagAndPrevTagSize

public synchronized void addHttpFlvSubscriber(Channel channel) {
		httpFLvSubscribers.add(channel);
		log.info("http flv subscriber : {} is added to stream :{}", channel, streamName);

		// 1.flv媒体信息描述
		byte[] meta = encodeFlvHeaderAndMetadata();
		channel.writeAndFlush(Unpooled.wrappedBuffer(meta));

		// 2. avcDecoderConfigurationRecord
		avcDecoderConfigurationRecord.setTimestamp(content.get(0).getTimestamp());
		byte[] config = encodeMediaAsFlvTagAndPrevTagSize(avcDecoderConfigurationRecord);
		channel.writeAndFlush(Unpooled.wrappedBuffer(config));

		// 3. write aacAudioSpecificConfig
		if (aacAudioSpecificConfig != null) {
			aacAudioSpecificConfig.setTimestamp(content.get(0).getTimestamp());
			byte[] aac = encodeMediaAsFlvTagAndPrevTagSize(aacAudioSpecificConfig);
			channel.writeAndFlush(Unpooled.wrappedBuffer(aac));
		}
		// 4. write content 数据转发

		for (RtmpMediaMessage msg : content) {
			channel.writeAndFlush(Unpooled.wrappedBuffer(encodeMediaAsFlvTagAndPrevTagSize(msg)));
		}

	}