Skip to content

Commit

Permalink
Merge pull request #9 from dpolakovics/add-7.1.4
Browse files Browse the repository at this point in the history
feat: add 7.1.4 and refactor a bit
  • Loading branch information
dpolakovics authored Nov 7, 2024
2 parents cc1634d + 7604171 commit fa98c7c
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 231 deletions.
18 changes: 0 additions & 18 deletions cmd/soundscape-sync/main.go

This file was deleted.

12 changes: 12 additions & 0 deletions internal/logic/sync-5.1.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package logic

func get5_1Arguments() []string {
return []string{
// best audio format so far on ios
"-filter_complex", "[1:a]apad[a2];[0:a][a2]amerge=inputs=2[out]",
"-c:a", "aac", "-b:a", "654k",
// mp4 output
// "-filter_complex", "[1:a]apad[a2];[0:a][a2]amerge=inputs=2,pan=5.1|c0=c0+c6|c1=c1+c7|c2=c2|c3=c3|c4=c4|c5=c5[out]",
// "-c:a", "eac3", "-ac", "6",
}
}
8 changes: 8 additions & 0 deletions internal/logic/sync-7.1.4.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package logic

func get7_1_4Arguments() []string {
return []string{
"-filter_complex",
"[1:a]apad[a2];[0:a][a2]amerge=inputs=2,pan=7.1.4|FL=c0+c12|FR=c1+c13|FC=c2|LFE=c3|BL=c6|BR=c7|SL=c4|SR=c5|TFL=c8|TFR=c9|TBL=c10|TBR=c11[out]",
}
}
99 changes: 0 additions & 99 deletions internal/logic/sync-atmos.go

This file was deleted.

87 changes: 2 additions & 85 deletions internal/logic/sync-stereo.go
Original file line number Diff line number Diff line change
@@ -1,90 +1,7 @@
package logic

import (
"context"
"fmt"
"os/exec"
"path/filepath"

"fyne.io/fyne/v2/widget"
)

func combineStereoFiles(folder1 string, folder2 string, outputFolder string, progress *widget.ProgressBar) error {
// Get list of audio files from both folders
files1, err := getAudioFiles(folder1)
if err != nil {
return err
}
files2, err := getAudioFiles(folder2)
if err != nil {
return err
}

if len(files1) != len(files2) {
return fmt.Errorf("the number of audio files in the two folders must be the same")
}

ffmpegPath, err := getFFmpegPath()
if err != nil {
return err
}

total := len(files1)

for index, file := range files1 {
duration, err := getDuration(file)
if err != nil {
return err
}

// Construct FFmpeg command
ext := filepath.Ext(files2[index])
newFileName := outputFolder + "/" + filepath.Base(files2[index])
newFileName = newFileName[:len(newFileName)-4] + "_synced" + ext
ctx, _ := context.WithCancel(context.Background())
arguments := []string{
"-i", file,
"-i", files2[index],
func getStereoArguments() []string {
return []string{
"-filter_complex", "[1:a]apad[a2];[0:a][a2]amerge=inputs=2,pan=stereo|c0<c0+c2|c1<c1+c3[out]",
}
arguments = append(arguments, getBaseArguments()...)
arguments = append(arguments, getCoverArtArguments(file, files2[index])...)
arguments = append(arguments, newFileName)
cmd := exec.CommandContext(ctx, ffmpegPath, arguments...)
cmd.SysProcAttr = getSysProcAttr()
stdout, err := cmd.StdoutPipe()
if err != nil {
return err
}

// Execute FFmpeg command
if err := cmd.Start(); err != nil {
return err
}

parseProgress(index, total, progress, stdout, duration)

if err := cmd.Wait(); err != nil {
return err
}
}

cleanupTemp()

progress.SetValue(1.0)
return nil
}

func getCoverArtFromMp3 (filename string) error {
ffmpegPath, err := getFFmpegPath()
if err != nil {
return err
}

cmd := exec.Command(ffmpegPath, "-i", filename, "cover.jpg")
if err := cmd.Run(); err != nil {
return err
}

return nil
}
137 changes: 108 additions & 29 deletions internal/logic/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package logic
import (
"io"
"bufio"
"context"
"fmt"
"io/ioutil"
"os"
Expand Down Expand Up @@ -38,35 +39,101 @@ func getAudioFiles(folder string) ([]string, error) {
}

func CombineFiles(folder1 string, folder2 string, outputFolder string, progress *widget.ProgressBar) error {
ffprobe, err := getFFProbePath()
if err != nil {
return err
}
// ffmpeg probe if first audio file in folder 1 has more than 2 channel
audioFiles1, err := getAudioFiles(folder1)
if err != nil {
return err
}
if len(audioFiles1) == 0 {
return fmt.Errorf("no audio files found")
}
cmd := exec.Command(ffprobe, "-v", "error", "-select_streams", "a:0", "-count_packets", "-show_entries", "stream=channels", "-of", "csv=p=0", audioFiles1[0])
out, err := cmd.Output()
if err != nil {
return err
}
// out contains a pipe and another space character at the end, so we need to trim it
channels, err := strconv.Atoi(strings.TrimSuffix(strings.TrimSpace(string(out)), ","))
if err != nil {
return err
}
if channels == 2 {
return combineStereoFiles(folder1, folder2, outputFolder, progress)
}
if channels == 6 {
return combineAtmosFiles(folder1, folder2, outputFolder, progress)
}
return fmt.Errorf("Currently only stereo and 5.1 Soundscapes are supported", channels)
// Get list of audio files from both folders
files1, err := getAudioFiles(folder1)
if err != nil {
return err
}
files2, err := getAudioFiles(folder2)
if err != nil {
return err
}

if len(files1) != len(files2) {
return fmt.Errorf("the number of audio files in the two folders must be the same")
}

ffmpeg, err := getFFmpegPath()
if err != nil {
return err
}

total := len(files1)

for index, file := range files1 {
channel , err := getChannelAmount(file)
if err != nil {
return err
}
duration, err := getDuration(file)
if err != nil {
return err
}

channelArguments, err := getChannelArguments(channel)
if err != nil {
return err
}

// Get output file name
ext := filepath.Ext(file)
newFileName := outputFolder + "/" + filepath.Base(files2[index])
newFileName = newFileName[:len(newFileName)-4] + "_synced" + ext

// Construct FFmpeg command
ctx, _ := context.WithCancel(context.Background())
arguments := []string{
"-i", file,
"-i", files2[index],
}
arguments = append(arguments, channelArguments...)
arguments = append(arguments, getBaseArguments()...)
arguments = append(arguments, getCoverArtArguments(file, files2[index])...)
arguments = append(arguments, newFileName)
cmd := exec.CommandContext(ctx, ffmpeg, arguments...)
cmd.SysProcAttr = getSysProcAttr()
stdout, err := cmd.StdoutPipe()
if err != nil {
// prepend error with text
err = fmt.Errorf("error creating ffmpeg command: %w", err)
return err
}

// Execute FFmpeg command
if err := cmd.Start(); err != nil {
err = fmt.Errorf("error at ffmpeg command start: %w", err)
return err
}

parseProgress(index, total, progress, stdout, duration)

if err := cmd.Wait(); err != nil {
err = fmt.Errorf("error at ffmpeg command wait: %w", err)
return err
}
}

cleanupTemp()

return nil
}

func getChannelAmount(file string) (int, error) {
ffprobe, err := getFFProbePath()
if err != nil {
return 0, err
}

cmd := exec.Command(ffprobe, "-v", "error", "-select_streams", "a:0", "-count_packets", "-show_entries", "stream=channels", "-of", "csv=p=0", file)
out, err := cmd.Output()
if err != nil {
return 0, err
}
channels, err := strconv.Atoi(strings.TrimSuffix(strings.TrimSpace(string(out)), ","))
if err != nil {
return 0, err
}
return channels, nil
}

func getDuration(filename string) (float64, error) {
Expand Down Expand Up @@ -105,6 +172,18 @@ func getBaseArguments() []string {
}
}

func getChannelArguments(channels int) ([]string, error) {
switch channels {
case 2:
return getStereoArguments(), nil
case 6:
return get5_1Arguments(), nil
case 12:
return get7_1_4Arguments(), nil
}
return nil, fmt.Errorf("Currently only stereo, 5.1 and 7.1.4 Soundscapes are supported")
}

func getCoverArtArguments(file1 string, file2 string) []string {
arguments := []string{}
if testCoverArt(file1) {
Expand Down

0 comments on commit fa98c7c

Please sign in to comment.