From f22753aed663ede6753713e080a0cd63254220e0 Mon Sep 17 00:00:00 2001
From: Jerry Yan <792602257@qq.com>
Date: Fri, 28 Feb 2025 10:21:10 +0800
Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0endpoint=EF=BC=8C=E6=B5=8B?=
 =?UTF-8?q?=E8=AF=95s3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 config.yaml             | 17 +++++++++----
 config/dto.go           | 11 ++++----
 fs/s3_adapter.go        | 56 +++++++++++++++++++++++++----------------
 util/file_recognizer.go |  2 +-
 util/parse_time.go      |  5 +++-
 5 files changed, 58 insertions(+), 33 deletions(-)

diff --git a/config.yaml b/config.yaml
index e7511b5..6f914cc 100644
--- a/config.yaml
+++ b/config.yaml
@@ -3,15 +3,22 @@ api:
   baseUrl: "http://127.0.0.1:8030/vpt/v1/scenic/3946669713328836608"
 record:
   storage:
-    type: "local"
     path: "/root/opt/"
+    type: "s3"
+    s3:
+      region: us-east-1
+      endpoint: http://192.168.55.101:9000
+      bucket: opt
+      prefix:
+      akId: 5vzfDiMztKO6VLvygoeX
+      akSec: Ot77u2kdVTm8zfQgExFrsm7xlGecxsiR6jk1idXM
   duration: 60
 devices:
   - deviceNo: "34020000001322200001"
     name: "192.168.55.201"
     path: "/root/opt/34020000001322200001/"
 fileName:
-  timeSplit: "-"
-  dateSeparator: "-"
-  fileExt: "dav"
-  unFinExt: "dav_"
\ No newline at end of file
+  timeSplit: "_"
+  dateSeparator: ""
+  fileExt: "ts"
+  unFinExt: "ts"
\ No newline at end of file
diff --git a/config/dto.go b/config/dto.go
index d0ea9e7..e43dd07 100644
--- a/config/dto.go
+++ b/config/dto.go
@@ -16,11 +16,12 @@ type StorageConfig struct {
 }
 
 type S3Config struct {
-	Region string `mapstructure:"region"`
-	Bucket string `mapstructure:"bucket"`
-	Prefix string `mapstructure:"prefix"`
-	AkId   string `mapstructure:"akId"`
-	AkSec  string `mapstructure:"akSec"`
+	Region   string `mapstructure:"region"`
+	Endpoint string `mapstructure:"endpoint"`
+	Bucket   string `mapstructure:"bucket"`
+	Prefix   string `mapstructure:"prefix"`
+	AkId     string `mapstructure:"akId"`
+	AkSec    string `mapstructure:"akSec"`
 }
 
 type DeviceMapping struct {
diff --git a/fs/s3_adapter.go b/fs/s3_adapter.go
index f146290..5f59937 100644
--- a/fs/s3_adapter.go
+++ b/fs/s3_adapter.go
@@ -12,7 +12,6 @@ import (
 	"time"
 
 	"github.com/aws/aws-sdk-go-v2/aws"
-	awsConfig "github.com/aws/aws-sdk-go-v2/config"
 	"github.com/aws/aws-sdk-go-v2/service/s3"
 )
 
@@ -23,10 +22,20 @@ type S3Adapter struct {
 
 func (s *S3Adapter) getClient() (*s3.Client, error) {
 	if s.s3Client == nil {
+		const defaultRegion = "us-east-1"
+		resolver := aws.EndpointResolverFunc(func(service, region string) (aws.Endpoint, error) {
+			return aws.Endpoint{
+				PartitionID:       "aws",
+				URL:               s.StorageConfig.S3.Endpoint, // or where ever you ran minio
+				SigningRegion:     defaultRegion,
+				HostnameImmutable: true,
+			}, nil
+		})
 		creds := credentials.NewStaticCredentialsProvider(s.StorageConfig.S3.AkId, s.StorageConfig.S3.AkSec, "")
-		cfg, err := awsConfig.LoadDefaultConfig(context.TODO(), awsConfig.WithCredentialsProvider(creds))
-		if err != nil {
-			return nil, err
+		cfg := aws.Config{
+			Credentials:      creds,
+			Region:           defaultRegion,
+			EndpointResolver: resolver,
 		}
 		s.s3Client = s3.NewFromConfig(cfg)
 	}
@@ -43,7 +52,11 @@ func (s *S3Adapter) GetFileList(dirPath string, relDt time.Time) ([]dto.File, er
 		Prefix: aws.String(path.Join(s.StorageConfig.S3.Prefix, dirPath)),
 	}
 
-	result, err := s.s3Client.ListObjectsV2(context.TODO(), listObjectsInput)
+	client, err := s.getClient()
+	if err != nil {
+		return nil, err
+	}
+	result, err := client.ListObjectsV2(context.TODO(), listObjectsInput)
 	if err != nil {
 		return nil, err
 	}
@@ -51,23 +64,24 @@ func (s *S3Adapter) GetFileList(dirPath string, relDt time.Time) ([]dto.File, er
 	var fileList []dto.File
 	for _, object := range result.Contents {
 		key := *object.Key
-		if util.IsVideoFile(path.Base(key)) {
-			startTime, stopTime, err := util.ParseStartStopTime(path.Base(key), relDt)
-			if err != nil {
-				continue
-			}
-			if startTime.Equal(stopTime) || stopTime.IsZero() {
-				stopTime = stopTime.Add(time.Second * time.Duration(config.Config.Record.Duration))
-			}
-			fileList = append(fileList, dto.File{
-				BasePath:  s.StorageConfig.S3.Bucket,
-				Name:      path.Base(key),
-				Path:      path.Dir(key),
-				Url:       key,
-				StartTime: startTime,
-				EndTime:   stopTime,
-			})
+		if !util.IsVideoFile(path.Base(key)) {
+			continue
 		}
+		startTime, stopTime, err := util.ParseStartStopTime(path.Base(key), relDt)
+		if err != nil {
+			continue
+		}
+		if startTime.Equal(stopTime) || stopTime.IsZero() {
+			stopTime = stopTime.Add(time.Second * time.Duration(config.Config.Record.Duration))
+		}
+		fileList = append(fileList, dto.File{
+			BasePath:  s.StorageConfig.S3.Bucket,
+			Name:      path.Base(key),
+			Path:      path.Dir(key),
+			Url:       key,
+			StartTime: startTime,
+			EndTime:   stopTime,
+		})
 	}
 	sort.Slice(fileList, func(i, j int) bool {
 		return fileList[i].StartTime.Before(fileList[j].StartTime)
diff --git a/util/file_recognizer.go b/util/file_recognizer.go
index 01ce9ba..8a53c20 100644
--- a/util/file_recognizer.go
+++ b/util/file_recognizer.go
@@ -6,5 +6,5 @@ func IsVideoFile(name string) bool {
 	if name == "" {
 		return false
 	}
-	return name[len(name)-len(config.Config.FileName.FileExt):] == config.Config.FileName.FileExt || name[len(name)-len(config.Config.FileName.UnfinishedFileExt):] == config.Config.FileName.UnfinishedFileExt
+	return (name[len(name)-len(config.Config.FileName.FileExt):] == config.Config.FileName.FileExt) || (name[len(name)-len(config.Config.FileName.UnfinishedFileExt):] == config.Config.FileName.UnfinishedFileExt)
 }
diff --git a/util/parse_time.go b/util/parse_time.go
index 349a35e..678f713 100644
--- a/util/parse_time.go
+++ b/util/parse_time.go
@@ -10,13 +10,16 @@ import (
 
 func ParseStartStopTime(filePath string, relativeDate time.Time) (time.Time, time.Time, error) {
 	split := strings.Split(filePath, config.Config.FileName.TimeSplit)
-	if len(split) != 2 {
+	if len(split) == 0 {
 		return time.Time{}, time.Time{}, fmt.Errorf("无法解析时间范围")
 	}
 	startTime, err := ParseTime(split[0], relativeDate)
 	if err != nil {
 		return time.Time{}, time.Time{}, err
 	}
+	if len(split) == 1 {
+		return startTime, startTime, nil
+	}
 	stopTime, err := ParseTime(split[1], relativeDate)
 	if err != nil {
 		return startTime, startTime, nil