vadviktor
7/7/2016 - 2:49 PM

Convert mp3/flac files to aac, recursively reading given base directory, working with 3 goroutines in a worker pool.

Convert mp3/flac files to aac, recursively reading given base directory, working with 3 goroutines in a worker pool.

package main

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

func main() {
	if len(os.Args) == 1 {
		fmt.Println("Please specify a base directory!")
		os.Exit(1)
	}

	fileList := []string{}
	err := filepath.Walk(os.Args[1], func(path string, f os.FileInfo, err error) error {
		switch filepath.Ext(path) {
		case
			".mp3",
			".flac":
			fileList = append(fileList, path)
		}
		return nil
	})
	if err != nil {
		fmt.Println(err)
	}

	jobLength := len(fileList)

	jobs := make(chan string, jobLength)
	results := make(chan string, jobLength)

	for i := 0; i <= 2; i++ {
		go worker(jobs, results)
	}

	for j := 0; j < jobLength; j++ {
		jobs <- fileList[j]
	}
	close(jobs)

	for k := 0; k < jobLength; k++ {
		<-results
	}
}

func worker(jobs <-chan string, results chan<- string) {
	for j := range jobs {
		results <- convertToAac(j)
	}
}

func convertToAac(filePath string) string {
	fmt.Println("Converting: ", filePath)

	destName := strings.TrimSuffix(filePath, ".flac")
	destName = strings.TrimSuffix(destName, ".mp3")
	destName = destName + ".m4a"

	// no text output
	// always override file
	// no video channel
	// use aac with CBR 256k quality
	cmd := exec.Command("ffmpeg", "-v", "0", "-y", "-i", filePath, "-vn", "-c:a", "aac", "-b:a", "256k", destName)
	var out bytes.Buffer
	cmd.Stdout = &out
	err := cmd.Run()
	if err != nil {
		log.Fatal("ffmpeg command exited: ", err)
	}

	fmt.Println("Done converting: ", filePath)

	return out.String()
}