diff --git a/hls/hls_stream.go b/hls/hls_stream.go index 4cf1e44..3c24bff 100644 --- a/hls/hls_stream.go +++ b/hls/hls_stream.go @@ -13,10 +13,8 @@ type tsContext struct { writeBuffer []byte writeBufferSize int - duration int - playlistLength int - url string - path string + url string + path string file *os.File } @@ -31,6 +29,7 @@ type Stream struct { m3u8Name string tsFormat string dir string + duration int m3u8File *os.File } @@ -58,6 +57,7 @@ func NewTransStream(url, m3u8Name, tsFormat, dir string, segmentDuration, playli m3u8Name: m3u8Name, tsFormat: tsFormat, dir: dir, + duration: segmentDuration, } muxer := libmpeg.NewTSMuxer() @@ -68,8 +68,6 @@ func NewTransStream(url, m3u8Name, tsFormat, dir string, segmentDuration, playli segmentSeq: 0, writeBuffer: make([]byte, 1024*1024), writeBufferSize: 0, - duration: segmentDuration, - playlistLength: playlistLength, } stream_.muxer = muxer @@ -83,7 +81,8 @@ func (t *Stream) Input(packet utils.AVPacket) error { return fmt.Errorf("track not available") } - if utils.AVMediaTypeVideo == packet.MediaType() && packet.KeyFrame() || t.context.file == nil { + //创建一下个切片 + if (!t.ExistVideo || utils.AVMediaTypeVideo == packet.MediaType() && packet.KeyFrame()) && float32(t.muxer.Duration())/90000 >= float32(t.duration) { if err := t.createSegment(); err != nil { return err } @@ -116,7 +115,7 @@ func (t *Stream) AddTrack(stream utils.AVStream) error { } func (t *Stream) WriteHeader() error { - return nil + return t.createSegment() } func (t *Stream) onTSWrite(data []byte) { diff --git a/hls/m3u8.go b/hls/m3u8.go index b70708c..62fca69 100644 --- a/hls/m3u8.go +++ b/hls/m3u8.go @@ -59,18 +59,11 @@ type Segment struct { } type m3u8Writer struct { - stringBuffer *bytes.Buffer - targetDuration int - playlist *stream.Queue + stringBuffer *bytes.Buffer + playlist *stream.Queue } func (m *m3u8Writer) AddSegment(duration float32 /*title string,*/, url string, sequence int) { - //影响播放器缓存. - round := int(math.Ceil(float64(duration))) - if round > m.targetDuration { - m.targetDuration = round - } - if m.playlist.IsFull() { m.playlist.Pop() } @@ -78,6 +71,31 @@ func (m *m3u8Writer) AddSegment(duration float32 /*title string,*/, url string, m.playlist.Push(Segment{duration: duration, url: url, sequence: sequence}) } +func (m *m3u8Writer) targetDuration() int { + var targetDuration int + head, tail := m.playlist.Data() + + compute := func(playlist []interface{}) { + for _, segment := range playlist { + //影响播放器缓存. + round := int(math.Ceil(float64(segment.(Segment).duration))) + if round > targetDuration { + targetDuration = round + } + } + } + + if head != nil { + compute(head) + } + + if tail != nil { + compute(tail) + } + + return targetDuration +} + func (m *m3u8Writer) ToString() string { //暂时只实现简单的播放列表 head, tail := m.playlist.Data() @@ -90,7 +108,7 @@ func (m *m3u8Writer) ToString() string { //暂时只实现第三个版本 m.stringBuffer.WriteString("#EXT-X-VERSION:3\r\n") m.stringBuffer.WriteString("#EXT-X-TARGETDURATION:") - m.stringBuffer.WriteString(strconv.Itoa(m.targetDuration)) + m.stringBuffer.WriteString(strconv.Itoa(m.targetDuration())) m.stringBuffer.WriteString("\r\n") m.stringBuffer.WriteString("#ExtXMediaSequence:") m.stringBuffer.WriteString(strconv.Itoa(head[0].(Segment).sequence)) diff --git a/main.go b/main.go index 30f95ec..3d036a2 100644 --- a/main.go +++ b/main.go @@ -21,7 +21,7 @@ func CreateTransStream(source stream.ISource, protocol stream.Protocol, streams m3u8Name := id + ".m3u8" tsFormat := id + "_%d.ts" - transStream, err := hls.NewTransStream("/live/hls/", m3u8Name, tsFormat, "../tmp/", 2, 10) + transStream, err := hls.NewTransStream("", m3u8Name, tsFormat, "../tmp/", 2, 10) if err != nil { panic(err) } diff --git a/rtmp/rtmp_server_test.go b/rtmp/rtmp_server_test.go index 0db7c3d..3f78449 100644 --- a/rtmp/rtmp_server_test.go +++ b/rtmp/rtmp_server_test.go @@ -8,7 +8,7 @@ import ( "testing" ) -func CreateTransStream(protocol stream.Protocol, streams []utils.AVStream) stream.ITransStream { +func CreateTransStream(source stream.ISource, protocol stream.Protocol, streams []utils.AVStream) stream.ITransStream { if stream.ProtocolRtmp == protocol { return NewTransStream(librtmp.ChunkSize) } diff --git a/stream/trans_stream.go b/stream/trans_stream.go index 930c52d..aec34ce 100644 --- a/stream/trans_stream.go +++ b/stream/trans_stream.go @@ -89,7 +89,7 @@ type TransStreamImpl struct { Tracks []utils.AVStream transBuffer MemoryPool //每个TransStream也缓存封装后的流 Completed bool - existVideo bool + ExistVideo bool } func (t *TransStreamImpl) Input(packet utils.AVPacket) error { @@ -99,7 +99,7 @@ func (t *TransStreamImpl) Input(packet utils.AVPacket) error { func (t *TransStreamImpl) AddTrack(stream utils.AVStream) error { t.Tracks = append(t.Tracks, stream) if utils.AVMediaTypeVideo == stream.Type() { - t.existVideo = true + t.ExistVideo = true } return nil }