2020-05-15 15:23:21 +02:00
|
|
|
package scanner
|
|
|
|
|
2020-05-17 21:28:42 +02:00
|
|
|
import (
|
|
|
|
"fmt"
|
2020-05-17 21:49:29 +02:00
|
|
|
"io/ioutil"
|
2020-05-17 21:28:42 +02:00
|
|
|
"log"
|
2020-05-17 21:49:29 +02:00
|
|
|
"os"
|
2020-05-17 21:28:42 +02:00
|
|
|
"os/exec"
|
2021-03-03 13:32:44 +01:00
|
|
|
"strings"
|
2020-05-15 15:23:21 +02:00
|
|
|
|
2020-05-17 21:28:42 +02:00
|
|
|
"github.com/pkg/errors"
|
|
|
|
)
|
2020-05-17 16:08:58 +02:00
|
|
|
|
2020-09-23 14:34:26 +02:00
|
|
|
func InitializeExecutableWorkers() {
|
|
|
|
DarktableCli = newDarktableWorker()
|
|
|
|
FfmpegCli = newFfmpegWorker()
|
|
|
|
}
|
|
|
|
|
|
|
|
var DarktableCli *DarktableWorker = nil
|
|
|
|
var FfmpegCli *FfmpegWorker = nil
|
2020-07-09 15:07:39 +02:00
|
|
|
|
|
|
|
type ExecutableWorker interface {
|
|
|
|
Path() string
|
|
|
|
}
|
|
|
|
|
2020-05-17 21:49:29 +02:00
|
|
|
type DarktableWorker struct {
|
|
|
|
path string
|
2020-05-15 15:23:21 +02:00
|
|
|
}
|
|
|
|
|
2020-07-09 15:07:39 +02:00
|
|
|
type FfmpegWorker struct {
|
|
|
|
path string
|
|
|
|
}
|
|
|
|
|
2020-09-23 14:34:26 +02:00
|
|
|
func newDarktableWorker() *DarktableWorker {
|
2020-05-17 21:49:29 +02:00
|
|
|
path, err := exec.LookPath("darktable-cli")
|
2020-05-15 15:23:21 +02:00
|
|
|
if err != nil {
|
2020-05-17 21:49:29 +02:00
|
|
|
log.Println("Executable worker not found: darktable")
|
2020-05-17 21:28:42 +02:00
|
|
|
} else {
|
2021-03-03 13:32:44 +01:00
|
|
|
version, err := exec.Command(path, "--version").Output()
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Error getting version of darktable: %s\n", err)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Printf("Found executable worker: darktable (%s)\n", strings.Split(string(version), "\n")[0])
|
2020-05-15 15:23:21 +02:00
|
|
|
|
2020-09-23 14:34:26 +02:00
|
|
|
return &DarktableWorker{
|
|
|
|
path: path,
|
|
|
|
}
|
2020-05-15 15:23:21 +02:00
|
|
|
}
|
2020-09-23 14:34:26 +02:00
|
|
|
|
|
|
|
return nil
|
2020-05-15 15:23:21 +02:00
|
|
|
}
|
|
|
|
|
2020-09-23 14:34:26 +02:00
|
|
|
func newFfmpegWorker() *FfmpegWorker {
|
2020-07-09 15:07:39 +02:00
|
|
|
path, err := exec.LookPath("ffmpeg")
|
|
|
|
if err != nil {
|
|
|
|
log.Println("Executable worker not found: ffmpeg")
|
|
|
|
} else {
|
2021-03-03 13:32:44 +01:00
|
|
|
version, err := exec.Command(path, "-version").Output()
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Error getting version of ffmpeg: %s\n", err)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Printf("Found executable worker: ffmpeg (%s)\n", strings.Split(string(version), "\n")[0])
|
2020-07-09 15:07:39 +02:00
|
|
|
|
2020-09-23 14:34:26 +02:00
|
|
|
return &FfmpegWorker{
|
|
|
|
path: path,
|
|
|
|
}
|
2020-07-09 15:07:39 +02:00
|
|
|
}
|
2020-09-23 14:34:26 +02:00
|
|
|
|
|
|
|
return nil
|
2020-07-09 15:07:39 +02:00
|
|
|
}
|
|
|
|
|
2020-05-17 21:49:29 +02:00
|
|
|
func (worker *DarktableWorker) IsInstalled() bool {
|
2020-09-23 14:34:26 +02:00
|
|
|
return worker != nil
|
2020-05-15 16:36:02 +02:00
|
|
|
}
|
|
|
|
|
2020-07-09 15:07:39 +02:00
|
|
|
func (worker *FfmpegWorker) IsInstalled() bool {
|
2020-09-23 14:34:26 +02:00
|
|
|
return worker != nil
|
2020-07-09 15:07:39 +02:00
|
|
|
}
|
|
|
|
|
2020-05-17 21:49:29 +02:00
|
|
|
func (worker *DarktableWorker) EncodeJpeg(inputPath string, outputPath string, jpegQuality int) error {
|
|
|
|
tmpDir, err := ioutil.TempDir("/tmp", "photoview-darktable")
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
defer os.RemoveAll(tmpDir)
|
|
|
|
|
|
|
|
args := []string{
|
|
|
|
inputPath,
|
|
|
|
outputPath,
|
|
|
|
"--core",
|
|
|
|
"--conf",
|
|
|
|
fmt.Sprintf("plugins/imageio/format/jpeg/quality=%d", jpegQuality),
|
|
|
|
"--configdir",
|
|
|
|
tmpDir,
|
2020-05-17 21:28:42 +02:00
|
|
|
}
|
|
|
|
|
2020-05-17 21:49:29 +02:00
|
|
|
cmd := exec.Command(worker.path, args...)
|
2020-05-15 15:23:21 +02:00
|
|
|
|
|
|
|
if err := cmd.Run(); err != nil {
|
2020-05-17 21:49:29 +02:00
|
|
|
return errors.Wrapf(err, "encoding image using: %s %v", worker.path, args)
|
2020-05-15 15:23:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-07-09 15:07:39 +02:00
|
|
|
func (worker *FfmpegWorker) EncodeMp4(inputPath string, outputPath string) error {
|
|
|
|
args := []string{
|
|
|
|
"-i",
|
|
|
|
inputPath,
|
|
|
|
"-vcodec", "h264",
|
|
|
|
"-acodec", "aac",
|
2020-07-11 13:13:31 +02:00
|
|
|
"-vf", "scale='min(1080,iw)':'min(1080,ih)':force_original_aspect_ratio=decrease",
|
2020-07-09 15:07:39 +02:00
|
|
|
outputPath,
|
|
|
|
}
|
|
|
|
|
|
|
|
cmd := exec.Command(worker.path, args...)
|
|
|
|
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
|
|
return errors.Wrapf(err, "encoding video using: %s", worker.path)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
2020-07-11 13:39:11 +02:00
|
|
|
|
|
|
|
func (worker *FfmpegWorker) EncodeVideoThumbnail(inputPath string, outputPath string, mediaData *EncodeMediaData) error {
|
|
|
|
|
|
|
|
metadata, err := mediaData.VideoMetadata()
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrapf(err, "get metadata to encode video thumbnail (%s)", inputPath)
|
|
|
|
}
|
|
|
|
|
|
|
|
thumbnailOffsetSeconds := fmt.Sprintf("%d", int(metadata.Format.DurationSeconds*0.25))
|
|
|
|
|
|
|
|
args := []string{
|
|
|
|
"-i",
|
|
|
|
inputPath,
|
|
|
|
"-vframes", "1", // output one frame
|
|
|
|
"-an", // disable audio
|
|
|
|
"-vf", "scale='min(1024,iw)':'min(1024,ih)':force_original_aspect_ratio=decrease",
|
|
|
|
"-ss", thumbnailOffsetSeconds, // grab frame at time offset
|
|
|
|
outputPath,
|
|
|
|
}
|
|
|
|
|
|
|
|
cmd := exec.Command(worker.path, args...)
|
|
|
|
|
|
|
|
if err := cmd.Run(); err != nil {
|
|
|
|
return errors.Wrapf(err, "encoding video using: %s", worker.path)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|