From bea4196004a3bab397e865ab91112c30226ff866 Mon Sep 17 00:00:00 2001 From: mohammad Date: Thu, 2 Sep 2021 14:35:25 +0430 Subject: [PATCH] add recover header file system --- crud.go | 24 +++++++++++++++++ go.mod | 2 +- pkg/virtualMedia/IO.go | 35 ++++++++++++++++--------- provider.go | 58 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 106 insertions(+), 13 deletions(-) diff --git a/crud.go b/crud.go index 0ae896e..6878dd7 100644 --- a/crud.go +++ b/crud.go @@ -31,6 +31,10 @@ func (arch *Archiver) OpenVirtualMediaFile(id uint32) (*virtualMedia.VirtualMedi return nil, err } + if len(vf.GetOptionalData()) == 0 { + arch.log.Warnv("optional data is empty", "id", vf.GetFileID()) + } + info, err := vInfo.Parse(vf.GetOptionalData()) if err != nil { return nil, err @@ -40,6 +44,26 @@ func (arch *Archiver) OpenVirtualMediaFile(id uint32) (*virtualMedia.VirtualMedi return vm, nil } +func (arch *Archiver) OpenVirtualMediaFileForHeaderRecovery(id uint32) (*virtualMedia.VirtualMedia, error) { + arch.crudMutex.Lock() + defer arch.crudMutex.Unlock() + //_, ok := arch.openFiles[id] + //if ok { + // return nil, fmt.Errorf("this ID: %v is opened before", id) + //} + vf, err := arch.fs.OpenVirtualFileForRecovery(id) + if err != nil { + return nil, err + } + + info := &vInfo.Info{} + + vm := virtualMedia.OpenVirtualMedia(vf.GetFileName(), id, arch.blockSize, vf, arch, info, arch.log) + + //arch.openFiles[id] = append(arch.openFiles[id], vm) + return vm, nil +} + func (arch *Archiver) RemoveVirtualMediaFile(id uint32) error { arch.crudMutex.Lock() defer arch.crudMutex.Unlock() diff --git a/go.mod b/go.mod index 4e88465..f5d7dea 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/fanap-infra/archiverMedia go 1.12 require ( - github.com/fanap-infra/fsEngine v0.5.3 + github.com/fanap-infra/fsEngine v0.5.4 github.com/fanap-infra/log v1.6.1 github.com/golang/protobuf v1.5.2 github.com/stretchr/testify v1.7.0 diff --git a/pkg/virtualMedia/IO.go b/pkg/virtualMedia/IO.go index 7b688d3..91558a1 100644 --- a/pkg/virtualMedia/IO.go +++ b/pkg/virtualMedia/IO.go @@ -34,11 +34,8 @@ func (vm *VirtualMedia) WriteFrame(frame *media.Packet) error { vm.info.StartTime = vm.frameChunk.StartTime } vm.info.EndTime = vm.frameChunk.EndTime - bInfo, err := proto.Marshal(vm.info) - if err != nil { - return err - } - err = vm.vFile.UpdateFileOptionalData(bInfo) + + err = vm.UpdateFileOptionalData() if err != nil { return err } @@ -64,6 +61,18 @@ func (vm *VirtualMedia) WriteFrame(frame *media.Packet) error { return nil } +func (vm *VirtualMedia) UpdateFileOptionalData() error { + bInfo, err := proto.Marshal(vm.info) + if err != nil { + return err + } + err = vm.vFile.UpdateFileOptionalData(bInfo) + if err != nil { + return err + } + return nil +} + func (vm *VirtualMedia) ReadFrame() (*media.Packet, error) { vm.rxMUX.Lock() defer vm.rxMUX.Unlock() @@ -100,8 +109,14 @@ func (vm *VirtualMedia) GotoTime(frameTime int64) (int64, error) { return vm.frameChunkRX.StartTime, nil } } + approximateByteIndex := int64(0) + if vm.info.EndTime - vm.info.StartTime != 0 { + approximateByteIndex = frameTime * int64(vm.vFile.GetFileSize()) / (vm.info.EndTime - vm.info.StartTime) + } else { + vm.log.Warnv("virtual media info time are wrong", "fileID",vm.fileID, + "endTime",vm.info.EndTime, "StartTime", vm.info.StartTime ) + } - approximateByteIndex := frameTime * int64(vm.vFile.GetFileSize()) / (vm.info.EndTime - vm.info.StartTime) vm.vfBuf = vm.vfBuf[:0] // moving forward is easier than backward moving approximateByteIndex = approximateByteIndex - int64(vm.blockSize*2) @@ -151,7 +166,7 @@ func (vm *VirtualMedia) Close() error { vm.rxMUX.Lock() defer vm.rxMUX.Unlock() - if len(vm.frameChunk.Packets) > 0 { + if len(vm.frameChunk.Packets) > 0 && !vm.readOnly { b, err := generateFrameChunk(vm.frameChunk) if err != nil { return err @@ -165,11 +180,7 @@ func (vm *VirtualMedia) Close() error { vm.info.StartTime = vm.frameChunk.StartTime } vm.info.EndTime = vm.frameChunk.EndTime - bInfo, err := proto.Marshal(vm.info) - if err != nil { - return err - } - err = vm.vFile.UpdateFileOptionalData(bInfo) + err = vm.UpdateFileOptionalData() if err != nil { return err } diff --git a/provider.go b/provider.go index 895e8f3..310aef8 100644 --- a/provider.go +++ b/provider.go @@ -2,6 +2,7 @@ package archiverMedia import ( "fmt" + "github.com/fanap-infra/archiverMedia/pkg/media" Header_ "github.com/fanap-infra/fsEngine/pkg/Header" "sync" @@ -62,6 +63,63 @@ func (p *Provider) ParseFileSystem(id uint32,path string, eventsHandler Events, arch.fs = fs arch.blockSize = fs.GetBlockSize() p.openedArchiver[path] = arch + + + return arch, nil +} + +func (p *Provider) RecoverHeaderFileSystem(id uint32,path string, blockSize uint32, eventsHandler Events, log *log.Logger, redisDB Header_.RedisDB) (*Archiver, error) { + p.crudMutex.Lock() + defer p.crudMutex.Unlock() + arch, ok := p.openedArchiver[path] + if ok { + return arch, nil + } + + arch = &Archiver{log: log, EventsHandler: eventsHandler, openFiles: make(map[uint32][]*virtualMedia.VirtualMedia)} + fs, err := fsEngine.RecoverHeaderFileSystem(id, path, blockSize, arch, log, redisDB) + if err != nil { + return nil, err + } + arch.fs = fs + arch.blockSize = fs.GetBlockSize() + p.openedArchiver[path] = arch + filesIndex := fs.GetFileList() + for i, fIndex := range filesIndex { + vm, err :=arch.OpenVirtualMediaFileForHeaderRecovery(fIndex.Id) + if err != nil { + p.log.Errorv("can not open virtual media file", "err", err.Error()) + continue + } + + vInfo := vm.GetInfo() + vInfo.StartTime = 0 + vInfo.EndTime = 0 + for { + frame, err := vm.ReadFrame() + if err == virtualMedia.EndOfFile { + log.Infov("end of file", "id", fIndex.Id, "i",i) + break + } else if err != nil { + log.Errorv("can not read frame", "id", fIndex.Id, "i",i, "err", err.Error()) + break + } + if frame.PacketType == media.PacketType_PacketVideo { + vInfo.EndTime = frame.Time + } + } + + err = vm.UpdateFileOptionalData() + if err != nil { + log.Errorv("can not update file optional data", + "id", fIndex.Id, "i",i, "err", err.Error()) + } + err =vm.Close() + if err != nil { + log.Errorv("can not close virtual media file", + "id", fIndex.Id, "i",i, "err", err.Error()) + } + } return arch, nil }