Files
seanime-docker/seanime-2.9.10/internal/mediastream/videofile/extract.go
2025-09-20 14:08:38 +01:00

83 lines
2.2 KiB
Go

package videofile
import (
"context"
"fmt"
"github.com/rs/zerolog"
"os"
"path/filepath"
"seanime/internal/util"
"seanime/internal/util/crashlog"
)
func GetFileSubsCacheDir(outDir string, hash string) string {
return filepath.Join(outDir, "videofiles", hash, "/subs")
}
func GetFileAttCacheDir(outDir string, hash string) string {
return filepath.Join(outDir, "videofiles", hash, "/att")
}
func ExtractAttachment(ffmpegPath string, path string, hash string, mediaInfo *MediaInfo, cacheDir string, logger *zerolog.Logger) (err error) {
logger.Debug().Str("hash", hash).Msgf("videofile: Starting media attachment extraction")
attachmentPath := GetFileAttCacheDir(cacheDir, hash)
subsPath := GetFileSubsCacheDir(cacheDir, hash)
_ = os.MkdirAll(attachmentPath, 0755)
_ = os.MkdirAll(subsPath, 0755)
subsDir, err := os.ReadDir(subsPath)
if err == nil {
if len(subsDir) == len(mediaInfo.Subtitles) {
logger.Debug().Str("hash", hash).Msgf("videofile: Attachments already extracted")
return
}
}
for _, sub := range mediaInfo.Subtitles {
if sub.Extension == nil || *sub.Extension == "" {
logger.Error().Msgf("videofile: Subtitle format is not supported")
return fmt.Errorf("videofile: Unsupported subtitle format")
}
}
// Instantiate a new crash logger
crashLogger := crashlog.GlobalCrashLogger.InitArea("ffmpeg")
defer crashLogger.Close()
crashLogger.LogInfof("Extracting attachments from %s", path)
// DEVNOTE: All paths fed into this command should be absolute
cmd := util.NewCmdCtx(
context.Background(),
ffmpegPath,
"-dump_attachment:t", "",
// override old attachments
"-y",
"-i", path,
)
// The working directory for the command is the attachment directory
cmd.Dir = attachmentPath
for _, sub := range mediaInfo.Subtitles {
if ext := sub.Extension; ext != nil {
cmd.Args = append(
cmd.Args,
"-map", fmt.Sprintf("0:s:%d", sub.Index),
"-c:s", "copy",
fmt.Sprintf("%s/%d.%s", subsPath, sub.Index, *ext),
)
}
}
cmd.Stdout = crashLogger.Stdout()
cmd.Stderr = crashLogger.Stdout()
err = cmd.Run()
if err != nil {
logger.Error().Err(err).Msgf("videofile: Error starting FFmpeg")
crashlog.GlobalCrashLogger.WriteAreaLogToFile(crashLogger)
}
return err
}