From: qydysky <32743305+qydysky@users.noreply.github.com> Date: Wed, 22 Feb 2023 18:44:05 +0000 (+0800) Subject: Fix fmp4未能找到起始段 X-Git-Tag: v0.6.3~5 X-Git-Url: http://127.0.0.1:8081/?a=commitdiff_plain;h=725fdf6597da4b60691c56109ec8ece91094b4bb;p=bili_danmu%2F.git Fix fmp4未能找到起始段 --- diff --git a/Reply/flvDecode.go b/Reply/flvDecode.go index 649687d..b445288 100644 --- a/Reply/flvDecode.go +++ b/Reply/flvDecode.go @@ -6,6 +6,7 @@ import ( // "math" + "github.com/dustin/go-humanize" F "github.com/qydysky/bili_danmu/F" ) @@ -26,6 +27,10 @@ var ( // this fuction read []byte and return flv header and all complete keyframe if possible. // complete keyframe means the video and audio tags between two video key frames tag func Search_stream_tag(buf []byte) (front_buf []byte, keyframe [][]byte, last_available_offset int, err error) { + if len(buf) > humanize.MByte*100 { + err = errors.New("buf too large") + return + } //get flv header(9byte) + FirstTagSize(4byte) if header_offset := bytes.Index(buf, flv_header_sign); header_offset != -1 { if header_offset+flv_header_size+previou_tag_size > len(buf) { diff --git a/Reply/fmp4Decode.go b/Reply/fmp4Decode.go index 7d5277a..fbe44e1 100644 --- a/Reply/fmp4Decode.go +++ b/Reply/fmp4Decode.go @@ -5,6 +5,7 @@ import ( "errors" "io" + "github.com/dustin/go-humanize" F "github.com/qydysky/bili_danmu/F" slice "github.com/qydysky/part/slice" ) @@ -65,9 +66,6 @@ func (t *Fmp4Decoder) Init_fmp4(buf []byte) (b []byte, err error) { var ftypI, ftypE, moovI, moovE int ies, e := decode(buf, "ftyp") - if len(ies) == 0 { - err = errors.New("未找到box") - } if e != nil { return } @@ -116,11 +114,14 @@ func (t *Fmp4Decoder) Init_fmp4(buf []byte) (b []byte, err error) { } func (t *Fmp4Decoder) Search_stream_fmp4(buf []byte, keyframes *slice.Buf[byte]) (cu int, err error) { + if len(buf) > humanize.MByte*100 { + err = errors.New("buf too large") + return + } if len(t.traks) == 0 { err = errors.New("未初始化traks") return } - if t.buf == nil { t.buf = slice.New[byte]() } @@ -199,9 +200,6 @@ func (t *Fmp4Decoder) Search_stream_fmp4(buf []byte, keyframes *slice.Buf[byte]) ) ies, e := decode(buf, "moof") - if len(ies) == 0 { - err = errors.New("未找到box") - } if e != nil { return } @@ -383,9 +381,15 @@ func deals(ies []ie, boxNames [][]string, fs []func([]ie) (breakloop bool)) (err func decode(buf []byte, reSyncboxName string) (m []ie, err error) { var cu int - for cu < len(buf) { + for cu < len(buf)-3 { boxName, i, e, E := searchBox(buf, &cu) if E != nil { + if errors.Is(E, io.EOF) { + if len(m) == 0 { + err = errors.New("未找到box") + } + return + } err = E if reSyncI := bytes.Index(buf[cu:], []byte(reSyncboxName)); reSyncI != -1 { cu += reSyncI - 4 diff --git a/Reply/fmp4Decode_test.go b/Reply/fmp4Decode_test.go index ff2b9d7..363a3f8 100644 --- a/Reply/fmp4Decode_test.go +++ b/Reply/fmp4Decode_test.go @@ -1,38 +1,63 @@ package reply import ( - // _ "embed" + "errors" + "fmt" + "io" "testing" - F "github.com/qydysky/bili_danmu/F" + "github.com/dustin/go-humanize" + file "github.com/qydysky/part/file" + slice "github.com/qydysky/part/slice" ) -// go:embed 32320131.m4s -var buf []byte - func Test_deal(t *testing.T) { - ies, _ := decode(buf, "moof") - err := deal(ies, - []string{"moof", "mfhd", - "traf", "tfhd", "tfdt", "trun", - "mdat"}, - func(m []ie) bool { - moofSN := int(F.Btoi(buf, m[1].i+12, 4)) - keyframeMoof := buf[m[5].i+20] == byte(0x02) - t.Log(moofSN, "frame", keyframeMoof, m[0].i, m[6].n, m[6].e) - return false - }) - t.Log("err", err) - err = deal(ies, - []string{"moof", "mfhd", - "traf", "tfhd", "tfdt", "trun", - "traf", "tfhd", "tfdt", "trun", - "mdat"}, - func(m []ie) bool { - moofSN := int(F.Btoi(buf, m[1].i+12, 4)) - keyframeMoof := buf[m[5].i+20] == byte(0x02) || buf[m[9].i+20] == byte(0x02) - t.Log(moofSN, "frame", keyframeMoof, m[0].i, m[10].n, m[10].e) - return false - }) - t.Log("err", err) + flog := file.New("E:\\test\\0.flv.log", 0, false) + flog.Delete() + defer flog.Close() + f := file.New("E:\\test\\0.mp4", 0, false) + defer f.Close() + + if f.IsDir() || !f.IsExist() { + t.Fatal("file not support") + } + + buf := make([]byte, humanize.MByte) + buff := slice.New[byte]() + max := 0 + fmp4Decoder := new(Fmp4Decoder) + fmp4KeyFrames := slice.New[byte]() + + for c := 0; true; c++ { + n, e := f.Read(buf) + if n == 0 && errors.Is(e, io.EOF) { + t.Log("reach end") + break + } + buff.Append(buf[:n]) + if s := buff.Size(); max < s { + max = s + } + if max > humanize.MByte*100 { + t.Log("reach max") + break + } + + front_buf, e := fmp4Decoder.Init_fmp4(buff.GetCopyBuf()) + if e != nil { + t.Fatal(e) + } + last_available_offset, e := fmp4Decoder.Search_stream_fmp4(buff.GetPureBuf(), fmp4KeyFrames) + if e != nil && e.Error() != "未初始化traks" { + t.Fatal(e) + } + if len(front_buf) != 0 { + t.Log("front_buf") + break + } + flog.Write([]byte(fmt.Sprintf("%d %d\n", c, len(front_buf))), true) + t.Log(c, len(front_buf)) + buff.RemoveFront(last_available_offset) + } + t.Log("max", humanize.Bytes(uint64(max))) } diff --git a/Reply/stream.go b/Reply/stream.go index 8b68abc..7a5478b 100644 --- a/Reply/stream.go +++ b/Reply/stream.go @@ -709,6 +709,8 @@ func (t *M4SStream) saveStreamFlv() (e error) { if strings.Contains(e.Error(), `no found available tag`) { continue } + //丢弃所有数据 + buff.Reset() } if len(front_buf)+len(keyframe) != 0 { if len(front_buf) != 0 {