From 21c4512b3a4e3932da98cced046a8c29dd16d975 Mon Sep 17 00:00:00 2001 From: yangjiechina <1534796060@qq.com> Date: Tue, 16 Jul 2024 23:02:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dhls=E6=8B=89=E6=B5=81?= =?UTF-8?q?=E5=8D=A1=E4=BD=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hls/hls_stream.go | 39 +++++++++++++++++++++++++-------------- hls/m3u8.go | 2 +- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/hls/hls_stream.go b/hls/hls_stream.go index 7b6afa8..8bfff53 100644 --- a/hls/hls_stream.go +++ b/hls/hls_stream.go @@ -116,6 +116,10 @@ func (t *transStream) onTSAlloc(size int) []byte { } func (t *transStream) flushSegment(end bool) error { + defer func() { + t.context.segmentSeq++ + }() + //将剩余数据写入缓冲区 if t.context.writeBufferSize > 0 { _, _ = t.context.file.Write(t.context.writeBuffer[:t.context.writeBufferSize]) @@ -135,7 +139,6 @@ func (t *transStream) flushSegment(end bool) error { duration := float32(t.muxer.Duration()) / 90000 t.m3u8.AddSegment(duration, t.context.url, t.context.segmentSeq, t.context.path) - if _, err := t.m3u8File.Seek(0, 0); err != nil { return err } @@ -165,25 +168,33 @@ func (t *transStream) flushSegment(end bool) error { // 创建一个新的ts切片 func (t *transStream) createSegment() error { t.muxer.Reset() - defer func() { - t.context.segmentSeq++ - }() - tsName := fmt.Sprintf(t.tsFormat, t.context.segmentSeq) - //ts文件 - t.context.path = fmt.Sprintf("%s/%s", t.dir, tsName) - //m3u8列表中切片的url - t.context.url = fmt.Sprintf("%s%s", t.tsUrl, tsName) + var tsFile *os.File + for { + tsName := fmt.Sprintf(t.tsFormat, t.context.segmentSeq) + //ts文件 + t.context.path = fmt.Sprintf("%s/%s", t.dir, tsName) + //m3u8列表中切片的url + t.context.url = fmt.Sprintf("%s%s", t.tsUrl, tsName) + + file, err := os.OpenFile(t.context.path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) + if err == nil { + tsFile = file + break + } - file, err := os.OpenFile(t.context.path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666) - if err != nil { log.Sugar.Errorf("创建ts切片文件失败 err:%s path:%s", err.Error(), t.context.path) - return err + if os.IsPermission(err) || os.IsTimeout(err) || os.IsNotExist(err) { + return err + } + + //继续创建, 认为是文件名冲突, 并且文件已经被打开. + t.context.segmentSeq++ } - t.context.file = file + t.context.file = tsFile _ = t.muxer.WriteHeader() - return err + return nil } func (t *transStream) Close() error { diff --git a/hls/m3u8.go b/hls/m3u8.go index 2abf9e9..3912e14 100644 --- a/hls/m3u8.go +++ b/hls/m3u8.go @@ -122,7 +122,7 @@ func (m *m3u8Writer) ToString() string { m.stringBuffer.WriteString("#EXT-X-TARGETDURATION:") m.stringBuffer.WriteString(strconv.Itoa(m.targetDuration())) m.stringBuffer.WriteString("\r\n") - m.stringBuffer.WriteString("#Ext-X-MEDIA-SEQUENCE:") + m.stringBuffer.WriteString("#EXT-X-MEDIA-SEQUENCE:") m.stringBuffer.WriteString(strconv.Itoa(head[0].(Segment).sequence)) m.stringBuffer.WriteString("\r\n")