engine icon indicating copy to clipboard operation
engine copied to clipboard

MemoryTS 输出的ts 文件 没有音频编码信息

Open mars79668 opened this issue 2 years ago • 4 comments

参考 hls 插件实现 ,使用memoryTs 输出的ts 文件没有音频编码信息,大致的代码如下: 直接使用hls 插件,输出的 ts 也无法获取 音视频信息,测试 拉流地址 http://huadonglive.starschinalive.com/stars/cjpd_stars-hd.m3u8?auth_key=1677980353-0-0-76a9f3c2dbaef16cf6b0f9d12b52eb5d

   func (hls *HLSWriter) OnEvent(event any) {
	switch v := event.(type) {
	case *track.Video:
		if hls.Audio != nil {
			hls.ts.WritePMTPacket(hls.Audio.CodecID, v.CodecID)
		} else {
			hls.ts.WritePMTPacket(0, v.CodecID)
		}
		hls.AddTrack(v)
	case *track.Audio:
		if hls.Video != nil {
			hls.ts.WritePMTPacket(v.CodecID, hls.Video.CodecID)
		} else {
			hls.ts.WritePMTPacket(v.CodecID, 0)
		}
		hls.AddTrack(v)
	case AudioFrame:
		pes := &mpegts.MpegtsPESFrame{
			Pid:                       mpegts.PID_AUDIO,
			IsKeyFrame:                false,
			ContinuityCounter:         hls.audio_cc,
			ProgramClockReferenceBase: uint64(v.DTS),
		}
		if err := hls.ts.WriteAudioFrame(v, pes); err != nil {
			hls.Error("WriteVideoFrame", zap.Error(err))
			return
		}
		hls.audio_cc = pes.ContinuityCounter
	case VideoFrame:
		if v.IFrame {
			// hls.ts.WriteTo(hFile)
			hls.frag(hls.Stream.Path, v.AbsTime, v)
		}
		pes := &mpegts.MpegtsPESFrame{
			Pid:                       mpegts.PID_VIDEO,
			IsKeyFrame:                v.IFrame,
			ContinuityCounter:         hls.video_cc,
			ProgramClockReferenceBase: uint64(v.DTS),
		}
		if err := hls.ts.WriteVideoFrame(v, pes); err != nil {
			hls.Error("WriteVideoFrame", zap.Error(err))
			return
		}
		hls.video_cc = pes.ContinuityCounter

	default:
		hls.Subscriber.OnEvent(event)
	}
}

ffprobe 信息如下

[mpegts @ 0x11fde40] PES packet size mismatch
    Last message repeated 5 times
[mpegts @ 0x11fde40] decoding for stream 0 failed
[mpegts @ 0x11fde40] decoding for stream 1 failed
[mpegts @ 0x11fde40] PES packet size mismatch
    Last message repeated 5 times
[mpegts @ 0x11fde40] Could not find codec parameters for stream 1 (Audio: aac ([15][0][0][0] / 0x000F), 0 channels, fltp): unspecified sample rate
Consider increasing the value for the 'analyzeduration' and 'probesize' options
Input #0, mpegts, from 'monibuca/output/hls/gtzy/cctv5P480/s15/cctv5-2303081101-18747-18765.ts':
  Duration: 00:00:00.27, start: 18765.786033, bitrate: 589 kb/s
  Program 1 
    Stream #0:0[0x101]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 640x480 [SAR 4:3 DAR 16:9], 30 fps, 30 tbr, 90k tbn, 60 tbc
    Stream #0:1[0x102]: Audio: aac ([15][0][0][0] / 0x000F), 0 channels, fltp

mars79668 avatar Mar 08 '23 04:03 mars79668

func (ts *MemoryTs) WriteTo(w io.Writer) (int64, error) {
	w.Write(mpegts.DefaultPATPacket)
	w.Write(ts.PMT)
	return ts.BLL.WriteTo(w)
}

注意写入的数据,PAT+PMT+PES

langhuihui avatar Mar 08 '23 05:03 langhuihui

最新版本 hls 插件不做任何改动测试 hls拉流发布,flv 订阅 可以预览播放, hls 订阅 无法播放,没有编码信息 最新版本的engin 好像不稳定, flv 播放大约 2-3 分钟后就无法播放了,订阅收不到内容

我看之前版本的代码,音频在 AudioDeConf AudioPacketToPES 有处理写入编码信息,视频 VideoPacketToPES 也有使用 Track.DecoderConfiguration 处理写入视频编码信息, memoryts 代码好像没有找到写入 音视频编码的信息

mars79668 avatar Mar 08 '23 05:03 mars79668

hls拉流发布我抽空测一下,估计之前的改动影响到了这个

langhuihui avatar Mar 08 '23 05:03 langhuihui

我提供的测试直播流,有我之前反馈的 ts 包乱序的问题,需要修正

package mpegts

import (
	"bytes"
	"errors"
	"io"
)

type mpegTsStreamStatus struct {
	pesPkt *MpegTsPESPacket
	frames int
}

func (s *MpegTsStream) Feed(ts io.Reader) (err error) {
	var reader bytes.Reader
	var lr io.LimitedReader
	lr.R = &reader
	var tsHeader MpegTsHeader
	tsData := make([]byte, TS_PACKET_SIZE)

	streamsStatus := make(map[uint16]*mpegTsStreamStatus)

	for {
		_, err = io.ReadFull(ts, tsData)
		if err == io.EOF {
			// 文件结尾 把最后面的数据发出去
			for _, ss := range streamsStatus {
				if ss.pesPkt != nil {
					s.PESChan <- ss.pesPkt
					ss.pesPkt = nil
				}
			}
			return nil
		} else if err != nil {
			return
		}
		reader.Reset(tsData)
		lr.N = TS_PACKET_SIZE
		if tsHeader, err = ReadTsHeader(&lr); err != nil {
			return
		}
		if tsHeader.SyncByte != 0x47 {
			return errors.New("sync byte error")
		}
		if tsHeader.Pid == PID_PAT {
			if s.PAT, err = ReadPAT(&lr); err != nil {
				return
			}
			continue
		}
		if len(s.PMT.Stream) == 0 {
			for _, v := range s.PAT.Program {
				if v.ProgramMapPID == tsHeader.Pid {
					if s.PMT, err = ReadPMT(&lr); err != nil {
						return
					}
				}
				continue
			}
		}
		for _, v := range s.PMT.Stream {
			if v.ElementaryPID == tsHeader.Pid {
				ss := streamsStatus[v.ElementaryPID]
				if ss == nil {
					ss = &mpegTsStreamStatus{}
					streamsStatus[v.ElementaryPID] = ss
				}
				if tsHeader.PayloadUnitStartIndicator == 1 {
					if ss.pesPkt != nil {
						s.PESChan <- ss.pesPkt
					}
					ss.pesPkt = &MpegTsPESPacket{}
					if ss.pesPkt.Header, err = ReadPESHeader(&lr); err != nil {
						return
					}
				}
				io.Copy(&ss.pesPkt.Payload, &lr)
			}
		}
	}
}

mars79668 avatar Mar 08 '23 06:03 mars79668