package fs import ( "ZhenTuLocalPassiveAdapter/config" "ZhenTuLocalPassiveAdapter/dto" "ZhenTuLocalPassiveAdapter/util" "context" "fmt" "github.com/aws/aws-sdk-go-v2/credentials" "log" "path" "sort" "time" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/service/s3" ) type S3Adapter struct { StorageConfig config.StorageConfig s3Client *s3.Client } 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 := aws.Config{ Credentials: creds, Region: defaultRegion, EndpointResolver: resolver, } s.s3Client = s3.NewFromConfig(cfg) } return s.s3Client, nil } func (s *S3Adapter) GetFileList(dirPath string, relDt time.Time) ([]dto.File, error) { if s.StorageConfig.S3.Bucket == "" { return nil, fmt.Errorf("未配置S3存储桶") } listObjectsInput := &s3.ListObjectsV2Input{ Bucket: aws.String(s.StorageConfig.S3.Bucket), Prefix: aws.String(path.Join(s.StorageConfig.S3.Prefix, dirPath)), } client, err := s.getClient() if err != nil { return nil, err } var fileList []dto.File var continuationToken *string for { if continuationToken != nil { listObjectsInput.ContinuationToken = continuationToken } result, err := client.ListObjectsV2(context.TODO(), listObjectsInput) if err != nil { return nil, err } for _, object := range result.Contents { key := *object.Key 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)) } presignClient := s3.NewPresignClient(client) request, err := presignClient.PresignGetObject(context.TODO(), &s3.GetObjectInput{ Bucket: aws.String(s.StorageConfig.S3.Bucket), Key: aws.String(key), }, func(presignOptions *s3.PresignOptions) { presignOptions.Expires = 10 * time.Minute }) if err != nil { log.Println("Error presigning GetObject request:", err) continue } fileList = append(fileList, dto.File{ BasePath: s.StorageConfig.S3.Bucket, Name: path.Base(key), Path: path.Dir(key), Url: request.URL, StartTime: startTime, EndTime: stopTime, }) } if !*result.IsTruncated { break } continuationToken = result.NextContinuationToken } sort.Slice(fileList, func(i, j int) bool { return fileList[i].StartTime.Before(fileList[j].StartTime) }) return fileList, nil }