func ConvertToMp4(ctx context.Context, ffmpegPath string,
	ffmpegLogPath string, aviFile string, soundFile string,
	outputFile string, quality float64,
	progressChan chan<- float64, errorChan chan<- error) {
	if filepath.Ext(outputFile) != ".mp4" {
		errorChan <- errors.New("output file must have the .mp4 extension")
		close(errorChan)
		return
	}
	if quality < 0 || quality > 1 {
		errorChan <- errors.New("quality setting must be a value between 0 and 1")
		close(errorChan)
		return
	}
	ffmpegQuality := uint64(math.Round(31.0 * (1 - quality)))
	args := []string{
		"-i", aviFile,
	}
	if soundFile != "" {
		args = append(args, "-i", soundFile)
		args = append(args, "-map", "0:v:0", "-map", "1:a:0?")
		args = append(args, "-c:a", "aac", "-b:a", "320k")
	}
	args = append(args, "-q", strconv.FormatUint(ffmpegQuality, 10))
	args = append(args, "-preset", "ultrafast")
	args = append(args, "-y")
	args = append(args, outputFile)
	runFFmpeg(ctx, ffmpegPath, args, ffmpegLogPath, progressChan, nil, errorChan)
}
ConvertToMp4 uses ffmpeg to convert the input file
into an MP4 file, taking the audio stream from another file.
If the sound file path is empty, no audio is added to the output file.
The encoding quality of the output file is determined
by the quality parameter, with 0.0 being the lowest
and 1.0 being highest possible quality setting.
The encoding progress is frequently written to the
progress channel as a value between 0.0 and 1.0.
Any errors encountered are sent to the error channel.
The error channel is closed when processing is finished.
package moshpit
import (
	"errors"
	"fmt"
	"math"
	"path/filepath"
	"strconv"
	"golang.org/x/net/context"
)
func ConvertToAvi(ctx context.Context, ffmpegPath string,
	ffmpegLogPath string, inputFile string, outputFile string, quality float64,
	iFrameIndices []uint64, progressChan chan<- float64,
	errorChan chan<- error) {
	if filepath.Ext(outputFile) != ".avi" {
		errorChan <- errors.New("output file must have the .avi extension")
		close(errorChan)
		return
	}
	if quality < 0 || quality > 1 {
		errorChan <- errors.New("quality setting must be a value between 0 and 1")
		close(errorChan)
		return
	}
	ffmpegQuality := uint64(math.Round(31.0 * (1 - quality)))
	args := []string{
		"-i", inputFile,
		"-an",
		"-q", strconv.FormatUint(ffmpegQuality, 10),
		"-y",
	}
	if iFrameIndices != nil {
		args = append(args, "-g", strconv.FormatInt(math.MaxInt32, 10))
		args = append(args, "-strict", "experimental")
		expr := "expr:"
		for i, frame := range iFrameIndices {
			if i != 0 {
				expr += "+"
			}
			expr += fmt.Sprintf("eq(n,%d)", frame)
		}
		args = append(args, "-force_key_frames", expr)
	}
	args = append(args, outputFile)
	runFFmpeg(ctx, ffmpegPath, args, ffmpegLogPath, progressChan, nil, errorChan)
}