feat: remove v1
This commit is contained in:
33
backend/common/service/testx/testing.go
Normal file
33
backend/common/service/testx/testing.go
Normal file
@@ -0,0 +1,33 @@
|
||||
package testx
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"backend/providers/hashids"
|
||||
|
||||
"git.ipao.vip/rogeecn/atom"
|
||||
"git.ipao.vip/rogeecn/atom/container"
|
||||
"github.com/rogeecn/fabfile"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
)
|
||||
|
||||
func Default(providers ...container.ProviderContainer) container.Providers {
|
||||
return append(container.Providers{
|
||||
hashids.DefaultProvider(),
|
||||
}, providers...)
|
||||
}
|
||||
|
||||
func Serve(providers container.Providers, t *testing.T, invoke any) {
|
||||
Convey("tests boot up", t, func() {
|
||||
file := fabfile.MustFind("config.toml")
|
||||
|
||||
localEnv := os.Getenv("ENV_LOCAL")
|
||||
if localEnv != "" {
|
||||
file = fabfile.MustFind("config." + localEnv + ".toml")
|
||||
}
|
||||
|
||||
So(atom.LoadProviders(file, providers), ShouldBeNil)
|
||||
So(container.Container.Invoke(invoke), ShouldBeNil)
|
||||
})
|
||||
}
|
||||
@@ -22,3 +22,7 @@ AppId = "wx45745a8c51091ae0"
|
||||
AppSecret = "2ab33bc79d9b47efa4abef19d66e1977"
|
||||
Token = "W8Xhw5TivYBgY"
|
||||
AesKey = "F6AqCxAV4W1eCrY6llJ2zapphKK49CQN3RgtPDrjhnI"
|
||||
|
||||
|
||||
[HashIDs]
|
||||
Salt = "LiXi.Y@140202"
|
||||
|
||||
@@ -4,6 +4,7 @@ go 1.22.0
|
||||
|
||||
require (
|
||||
git.ipao.vip/rogeecn/atom v1.0.10
|
||||
github.com/etherlabsio/go-m3u8 v1.0.0
|
||||
github.com/go-jet/jet/v2 v2.12.0
|
||||
github.com/gofiber/fiber/v3 v3.0.0-beta.3
|
||||
github.com/gofrs/uuid v4.4.0+incompatible
|
||||
@@ -14,6 +15,7 @@ require (
|
||||
github.com/lib/pq v1.10.9
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pressly/goose/v3 v3.23.0
|
||||
github.com/rogeecn/fabfile v1.4.0
|
||||
github.com/samber/lo v1.47.0
|
||||
github.com/sirupsen/logrus v1.9.3
|
||||
github.com/smartystreets/goconvey v1.6.4
|
||||
@@ -21,6 +23,7 @@ require (
|
||||
github.com/spf13/cast v1.5.1
|
||||
github.com/spf13/cobra v1.8.1
|
||||
github.com/spf13/viper v1.17.0
|
||||
github.com/stretchr/testify v1.9.0
|
||||
go.uber.org/dig v1.18.0
|
||||
golang.org/x/net v0.31.0
|
||||
golang.org/x/sync v0.9.0
|
||||
@@ -70,7 +73,6 @@ require (
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.10.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/stretchr/testify v1.9.0 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.55.0 // indirect
|
||||
|
||||
@@ -38,6 +38,7 @@ cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3f
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
git.ipao.vip/rogeecn/atom v1.0.10 h1:U/10G17rkULOAhgqGUD6rhcdJ5vJNxGv5gelAZTcJeU=
|
||||
git.ipao.vip/rogeecn/atom v1.0.10/go.mod h1:YY1nlkYnMpZxen5R64mblMWm+LJYyvWiw3P8P2eO7dY=
|
||||
github.com/AlekSi/pointer v1.0.0/go.mod h1:1kjywbfcPFCmncIxtk6fIEub6LKrfMz3gc5QKVOSOA8=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
@@ -70,6 +71,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
||||
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
|
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/etherlabsio/go-m3u8 v1.0.0 h1:d3HJVr8wlbvJO20ksKEyvDYf4bcM7v8YV3W83fHswL0=
|
||||
github.com/etherlabsio/go-m3u8 v1.0.0/go.mod h1:RzDiaXgaYnIEzZUmVUD/xMRFR7bY7U5JaCnp8XYLmXU=
|
||||
github.com/frankban/quicktest v1.2.2/go.mod h1:Qh/WofXFeiAFII1aEBu529AtJo6Zg2VHscnEsbBnJ20=
|
||||
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
|
||||
github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
@@ -301,6 +304,8 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rogeecn/atom v1.0.8 h1:Dr/pF3my7ZxB0OR5IN5Xw4ztjDsL+KpOHq31yxidb8w=
|
||||
github.com/rogeecn/atom v1.0.8/go.mod h1:BgKU29c4pVZFgumyvIr5rGTG1qEbIOrAQbAsd73cFSA=
|
||||
github.com/rogeecn/fabfile v1.4.0 h1:Rw7/7OH8cV4aRPw79Oa4hHHFKaC/ol+sNmGcB/usHaQ=
|
||||
github.com/rogeecn/fabfile v1.4.0/go.mod h1:EPwX7TtVcIWSLJkJAqxSzYjM/aV1Q0wymcaXqnMgzas=
|
||||
github.com/rogpeppe/clock v0.0.0-20190514195947-2896927a307a h1:3QH7VyOaaiUHNrA9Se4YQIRkDTCw1EJls9xTUCaCeRM=
|
||||
github.com/rogpeppe/clock v0.0.0-20190514195947-2896927a307a/go.mod h1:4r5QyqhjIWCcK8DO4KMclc5Iknq5qVBAlbYYzAbUScQ=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package medias
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
|
||||
"backend/providers/http"
|
||||
"database/sql"
|
||||
|
||||
"git.ipao.vip/rogeecn/atom"
|
||||
"git.ipao.vip/rogeecn/atom/container"
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package middlewares
|
||||
|
||||
import (
|
||||
"backend/modules/users"
|
||||
"backend/providers/jwt"
|
||||
"backend/providers/wechat"
|
||||
|
||||
"git.ipao.vip/rogeecn/atom/container"
|
||||
@@ -10,9 +12,13 @@ import (
|
||||
func Provide(opts ...opt.Option) error {
|
||||
if err := container.Container.Provide(func(
|
||||
client *wechat.Client,
|
||||
jwt *jwt.JWT,
|
||||
userSvc *users.Service,
|
||||
) (*Middlewares, error) {
|
||||
obj := &Middlewares{
|
||||
client: client,
|
||||
client: client,
|
||||
jwt: jwt,
|
||||
userSvc: userSvc,
|
||||
}
|
||||
if err := obj.Prepare(); err != nil {
|
||||
return nil, err
|
||||
|
||||
140
backend/modules/tasks/discover_medias.go
Normal file
140
backend/modules/tasks/discover_medias.go
Normal file
@@ -0,0 +1,140 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"backend/modules/medias"
|
||||
|
||||
"github.com/etherlabsio/go-m3u8/m3u8"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
log "github.com/sirupsen/logrus"
|
||||
hashids "github.com/speps/go-hashids/v2"
|
||||
)
|
||||
|
||||
// @provider
|
||||
type DiscoverMedias struct {
|
||||
hashId *hashids.HashID
|
||||
mediasSvc *medias.Service
|
||||
|
||||
log *logrus.Entry `inject:"false"`
|
||||
}
|
||||
|
||||
func (d *DiscoverMedias) Prepare() error {
|
||||
d.log = log.WithField("module", "DiscoverMedias")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DiscoverMedias) getHashID(ids ...int64) (string, error) {
|
||||
return d.hashId.EncodeInt64(ids)
|
||||
}
|
||||
|
||||
func (d *DiscoverMedias) getSubDirs(root string) ([]string, error) {
|
||||
fd, err := os.Open(root)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "open root directory: %s", root)
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
entries, err := fd.Readdir(-1)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "read root directory: %s", root)
|
||||
}
|
||||
|
||||
var paths []string
|
||||
for _, entry := range entries {
|
||||
if entry.IsDir() {
|
||||
paths = append(paths, entry.Name())
|
||||
}
|
||||
}
|
||||
|
||||
return paths, nil
|
||||
}
|
||||
|
||||
func (d *DiscoverMedias) globVideo(root string) []string {
|
||||
files := []string{}
|
||||
|
||||
exts := []string{"*.mp4", "*.MP4", "*.mov", "*.MOV"}
|
||||
|
||||
for _, ext := range exts {
|
||||
fs, _ := filepath.Glob(filepath.Join(root, ext))
|
||||
files = append(files, fs...)
|
||||
}
|
||||
|
||||
return files
|
||||
}
|
||||
|
||||
func (d *DiscoverMedias) globAudio(root string) []string {
|
||||
files := []string{}
|
||||
|
||||
exts := []string{"*.mp3", "*.MP3", "*.wav", "*.WAV"}
|
||||
|
||||
for _, ext := range exts {
|
||||
fs, _ := filepath.Glob(filepath.Join(root, ext))
|
||||
files = append(files, fs...)
|
||||
}
|
||||
|
||||
return files
|
||||
}
|
||||
|
||||
// ensureDirectory ensure the directory exists
|
||||
func (d *DiscoverMedias) ensureDirectory(dir string) error {
|
||||
st, err := os.Stat(dir)
|
||||
if os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
|
||||
return errors.Wrapf(err, "mkdir: %s", dir)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if !st.IsDir() {
|
||||
os.RemoveAll(dir)
|
||||
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
|
||||
return errors.Wrapf(err, "mkdir: %s", dir)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *DiscoverMedias) ffmpegVideoToM3U8(input string, output string) error {
|
||||
output = filepath.Join(output, "video")
|
||||
if err := d.ensureDirectory(output); err != nil {
|
||||
return errors.Wrapf(err, "ensure directory: %s", output)
|
||||
}
|
||||
|
||||
args := []string{
|
||||
"-i", input,
|
||||
"-c:v", "libx264",
|
||||
"-c:a", "aac",
|
||||
"-strict",
|
||||
"-2",
|
||||
"-f", "hls",
|
||||
"-hls_time", "10",
|
||||
"-hls_list_size", "0",
|
||||
"-hls_segment_filename", filepath.Join(output, "%d.ts"),
|
||||
filepath.Join(output, "index.m3u8"),
|
||||
}
|
||||
|
||||
log.Infof("cmd: ffmpeg %s", strings.Join(args, " "))
|
||||
logs, err := exec.Command("ffmpeg", args...).Output()
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "ffmpeg video to m3u8: %s", input)
|
||||
}
|
||||
|
||||
d.log.Infof("ffmpeg video to m3u8: %s", logs)
|
||||
return nil
|
||||
}
|
||||
|
||||
// parseM3u8File parse the m3u8 file
|
||||
func (d *DiscoverMedias) parseM3u8File(file string) (*m3u8.Playlist, error) {
|
||||
platList, err := m3u8.ReadFile(file)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "read m3u8 file:%s", file)
|
||||
}
|
||||
|
||||
return platList, nil
|
||||
}
|
||||
84
backend/modules/tasks/discover_medias_test.go
Normal file
84
backend/modules/tasks/discover_medias_test.go
Normal file
@@ -0,0 +1,84 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"backend/common/service/testx"
|
||||
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
"github.com/stretchr/testify/suite"
|
||||
"go.uber.org/dig"
|
||||
)
|
||||
|
||||
type DiscoverMediasInjectParams struct {
|
||||
dig.In
|
||||
Svc *DiscoverMedias
|
||||
}
|
||||
|
||||
type DiscoverMediasTestSuite struct {
|
||||
suite.Suite
|
||||
DiscoverMediasInjectParams
|
||||
}
|
||||
|
||||
func Test_DiscoverMedias(t *testing.T) {
|
||||
providers := testx.Default().With(
|
||||
Provide,
|
||||
)
|
||||
|
||||
testx.Serve(providers, t, func(params DiscoverMediasInjectParams) {
|
||||
suite.Run(t, &DiscoverMediasTestSuite{DiscoverMediasInjectParams: params})
|
||||
})
|
||||
}
|
||||
|
||||
func (t *DiscoverMediasTestSuite) Test_getHashID() {
|
||||
Convey("TestDiscoverMedias_getHashID", t.T(), func() {
|
||||
hashId, err := t.Svc.getHashID(10, 11, 12)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
t.T().Logf("HashID: %s", hashId)
|
||||
})
|
||||
}
|
||||
|
||||
func (t *DiscoverMediasTestSuite) Test_getSubDirs() {
|
||||
Convey("Test_getSubDirs", t.T(), func() {
|
||||
dirs, err := t.Svc.getSubDirs("/mnt/yangpingliang/动态曲谱")
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
t.T().Logf("Dirs: %+v", dirs)
|
||||
})
|
||||
}
|
||||
|
||||
func (t *DiscoverMediasTestSuite) Test_getVideo() {
|
||||
Convey("Test_getVideo", t.T(), func() {
|
||||
dirs := t.Svc.globVideo("/mnt/yangpingliang/动态曲谱/河北梆子伴奏《李慧娘》依然还我生前摸样")
|
||||
t.T().Logf("Dirs: %+v", dirs)
|
||||
})
|
||||
}
|
||||
|
||||
func (t *DiscoverMediasTestSuite) Test_getAudio() {
|
||||
Convey("Test_getAudio", t.T(), func() {
|
||||
dirs := t.Svc.globAudio("/mnt/yangpingliang/动态曲谱/河北梆子伴奏《李慧娘》依然还我生前摸样")
|
||||
t.T().Logf("Dirs: %+v", dirs)
|
||||
})
|
||||
}
|
||||
|
||||
func (t *DiscoverMediasTestSuite) Test_ffmpegVideoToM3U8() {
|
||||
Convey("Test_ffmpegVideoToM3U8", t.T(), func() {
|
||||
output := "/projects/mp-qvyun/backend/fixtures/medias/abc"
|
||||
os.RemoveAll(output)
|
||||
|
||||
err := t.Svc.ffmpegVideoToM3U8("/projects/mp-qvyun/backend/fixtures/medias/video.mp4", output)
|
||||
So(err, ShouldBeNil)
|
||||
})
|
||||
}
|
||||
|
||||
func (t *DiscoverMediasTestSuite) Test_parseM3u8File() {
|
||||
Convey("TestDiscoverMedias_parseM3u8File", t.T(), func() {
|
||||
file := "/projects/mp-qvyun/backend/fixtures/medias/abc/video/index.m3u8"
|
||||
playlist, err := t.Svc.parseM3u8File(file)
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
t.T().Logf("ListType: %+v", playlist)
|
||||
})
|
||||
}
|
||||
22
backend/modules/tasks/provider.gen.go
Executable file
22
backend/modules/tasks/provider.gen.go
Executable file
@@ -0,0 +1,22 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"git.ipao.vip/rogeecn/atom/container"
|
||||
"git.ipao.vip/rogeecn/atom/utils/opt"
|
||||
hashids "github.com/speps/go-hashids/v2"
|
||||
)
|
||||
|
||||
func Provide(opts ...opt.Option) error {
|
||||
if err := container.Container.Provide(func(
|
||||
hashId *hashids.HashID,
|
||||
) (*DiscoverMedias, error) {
|
||||
obj := &DiscoverMedias{
|
||||
hashId: hashId,
|
||||
}
|
||||
return obj, nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -17,7 +17,7 @@ func Provide(opts ...opt.Option) error {
|
||||
data := hashids.NewData()
|
||||
data.MinLength = int(config.MinLength)
|
||||
if data.MinLength == 0 {
|
||||
data.MinLength = 5
|
||||
data.MinLength = 10
|
||||
}
|
||||
|
||||
data.Salt = config.Salt
|
||||
@@ -25,8 +25,9 @@ func Provide(opts ...opt.Option) error {
|
||||
data.Salt = "default-salt-key"
|
||||
}
|
||||
|
||||
if config.Alphabet != "" {
|
||||
data.Alphabet = config.Alphabet
|
||||
data.Alphabet = config.Alphabet
|
||||
if config.Alphabet == "" {
|
||||
data.Alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
||||
}
|
||||
|
||||
return hashids.NewWithData(data)
|
||||
|
||||
@@ -1,3 +1,13 @@
|
||||
https://github.com/etherlabsio/go-m3u8
|
||||
|
||||
https://github.com/FlashFeiFei/m3u8Transmit/blob/main/main.go
|
||||
https://github.com/FlashFeiFei/m3u8Transmit/blob/main/main.go
|
||||
|
||||
|
||||
### mp4 -> ts
|
||||
ffmpeg -y -i video.mp4 -vcodec copy -acodec copy -vbsf h264_mp4toannexb video.ts
|
||||
|
||||
### ts -> m3u8
|
||||
ffmpeg -y -i video.ts -hls_time 10 -hls_segment_filename ./m3u8/s%d.ts ./m3u8/index.m3u8
|
||||
|
||||
### mp4 to m3u8
|
||||
ffmpeg -i input.mp4 -c:v libx264 -c:a aac -strict -2 -f hls output.m3u8
|
||||
Reference in New Issue
Block a user