diff --git a/writer/pkg/storage/file.go b/writer/pkg/storage/file.go index 769f04d..736a99c 100644 --- a/writer/pkg/storage/file.go +++ b/writer/pkg/storage/file.go @@ -399,39 +399,79 @@ func FileBytes(id, res, file string) (int64, error) { return size, nil } -// GetHeader -func GetHeader(id, res, file string) ([]string, error) { +// GetDurAndTracks reads .insit file and returns duration and tracks of the file. +func GetDurAndTracks(id, res, file string) (int, map[string]string, error) { // Open file for reading. f, err := os.Open(fmt.Sprintf("%s/%s/%s/%s", config.DirData, id, res, file)) if err != nil { - return nil, errors.New("opening file error for file: " + err.Error()) + return 0, nil, errors.New("opening file error for file: " + err.Error()) } defer f.Close() // Read StreamID. var streamIDLen int32 if err := binary.Read(f, binary.LittleEndian, &streamIDLen); err != nil { - return nil, errors.New("reading StreamID length error: " + err.Error()) + return 0, nil, errors.New("reading StreamID length error: " + err.Error()) } streamIDBytes := make([]byte, streamIDLen) if _, err := io.ReadFull(f, streamIDBytes); err != nil { - return nil, errors.New("reading StreamID error: " + err.Error()) + return 0, nil, errors.New("reading StreamID error: " + err.Error()) } // Read header of the file. var segLen int32 if err := binary.Read(f, binary.LittleEndian, &segLen); err != nil { - return nil, errors.New("reading header length error: " + err.Error()) + return 0, nil, errors.New("reading header length error: " + err.Error()) } segData := make([]byte, segLen) if _, err := io.ReadFull(f, segData); err != nil { - return nil, errors.New("reading header error: " + err.Error()) + return 0, nil, errors.New("reading header error: " + err.Error()) } headerReader := bytes.NewReader(segData) headerSeg, err := ReadHeaderSegment(headerReader) if err != nil { - return nil, errors.New("reading header error: " + err.Error()) + return 0, nil, errors.New("reading header error: " + err.Error()) } + + // Parse duration of a segment. + per, err := strconv.Atoi(headerSeg.Duration) + if err != nil { + return 0, nil, errors.New("parsing duration error: " + err.Error()) + } + + tracks := make(map[string]string, 2) + + for { + // Read segments length. + var segLen int32 + err := binary.Read(f, binary.LittleEndian, &segLen) + if err != nil { + if err == io.EOF { + break + } + return 0, nil, errors.New("read segments length error: " + err.Error()) + } + // Read segments data. + segData = make([]byte, segLen) + if _, err := io.ReadFull(f, segData); err != nil { + return 0, nil, errors.New("read segments error: " + err.Error()) + } + packetReader := bytes.NewReader(segData) + packets, err := ReadPacketSegment(packetReader) + if err != nil { + return 0, nil, errors.New("func readPacketSegment error: " + err.Error()) + } + + for _, pkt := range packets { + switch pkt.Type { + case PacketTypeH264: + tracks["video"] = "H264" + case PacketTypeLPCM: + tracks["audio"] = "LPCM" + } + } + } + return per, tracks, nil } // readString reads string length and then reads string data.