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 }