func runConvertToHLS(inPath string, outPath string, audioStreamIndex int, videoStreamIndex int, audioArgs []string, videoArgs []string) error {
	log.Printf("Converting to HLS with ffmpeg, audio: %+v; video: %+v\n", audioArgs, videoArgs)
	firstArgs := []string{
		"-i", inPath,  
		"-map", fmt.Sprintf("0:%d", videoStreamIndex),  
		"-map", fmt.Sprintf("0:%d", audioStreamIndex),  
	}
	lastArgs := []string{"-hls_list_size", "0", outPath}
	allArgs := append(append(append(firstArgs, audioArgs...), videoArgs...), lastArgs...)
	result, err := ffmpeg(allArgs)
	if err != nil {
		log.Println("Initial ffmpeg attempt failed, the output was as follows:")
		log.Println(string(result))
	}
	if err != nil && strings.Contains(string(result), "h264_mp4toannexb") {
		log.Println("Attempting to convert to HLS using h264_mp4toannexb option")
		allArgs := append(append(append(append(firstArgs, audioArgs...), videoArgs...), "-bsf:v", "h264_mp4toannexb"), lastArgs...)
		result2, err2 := ffmpeg(allArgs)
		if err2 != nil {
			log.Println("Second ffmpeg attempt failed, the output was as follows:")
			log.Println(string(result2))
		}
		return err2
	}
	return err
}
/ Converts to HLS. If it gets back an error about h264_mp4toannexb, it retries with the appropriate command.
package main
import (
	"errors"
	"fmt"
	"log"
	"os"
	"path/filepath"
	"strings"
)
type convertRenamedError struct {
	text string
}
func (e *convertRenamedError) Error() string {
	return "Something was wrong with this file that needs user intervention: " + e.text + ". Renamed the file so the user is forced to choose."
}
func convertToHLSAppropriately(inPath string, outPath string, config Config) error {
	if config.DebugSkipHLS {
		log.Println("Not converting to HLS due to DebugSkipHLS flag")
		return nil
	}
	log.Println("Probing, this sometimes takes a while...")
	probeResult, probeErr := probe(inPath)
	if probeErr != nil {
		return errors.New("Couldn't probe " + inPath)
	}
	log.Printf("Probed, found %v streams", len(probeResult.Streams))
	log.Printf("Probe result: %+v", probeResult)
	audioStreams := probeResult.audioStreams()
	videoStreams := probeResult.videoStreams()
	if len(videoStreams) == 0 {
		return errors.New("No video stream")
	}
	var audioStream ProbeStream
	if len(audioStreams) == 0 {
		return errors.New("No audio stream")
	} else if len(audioStreams) == 1 {
		audioStream = audioStreams[0]
	} else {
		indexFromFilename := audioStreamFromFile(inPath)
		if indexFromFilename == nil {
			log.Printf("Too many audio streams, splitting them out and forcing the user to choose one.")
			for _, stream := range audioStreams {
				args := []string{
					"-t", "180",  
					"-i", inPath,
					"-map", fmt.Sprintf("0:%d", stream.Index),
					"-ac", "1",  
					"-b:a", "64k",  
					inPath + fmt.Sprintf(".AudioStream%d preview.mp3", stream.Index),
				}
				ffmpeg(args)  
			}
			ext := filepath.Ext(inPath)  
			nameSansExt := strings.TrimSuffix(inPath, ext)
			newName := nameSansExt + ".AudioStreamX" + ext + ".please insert correct audio stream number then remove this"
			os.Rename(inPath, newName)
			return &convertRenamedError{text: "Too many audio streams"}
		} else {
			for _, stream := range audioStreams {
				if stream.Index == *indexFromFilename {
					audioStream = stream
				}
			}
			if audioStream.Index != *indexFromFilename {
				return errors.New("Couldn't find the stream with the index as per the filename")
			}
		}
	}
	var audioCommand []string
	if audioStream.Channel_layout == "stereo" && audioStream.Codec_name == "aac" {
		audioCommand = []string{"-acodec", "copy"}  
	} else if audioStream.Channel_layout == "stereo" {
		audioCommand = []string{"-strict", "experimental", "-b:a", "192k"}  
	} else if audioStream.Channel_layout == "5.1" {  
		log.Println("Using custom downmix from 5.1 to stereo that preserves bass and speech")
		audioCommand = []string{"-strict", "experimental", "-b:a", "192k", "-af", "pan=stereo|FL<FL+BL+FC+LFE|FR<FR+BR+FC+LFE"}
	} else if audioStream.Channel_layout == "5.1(side)" {  
		log.Println("Using custom downmix from 5.1 to stereo that preserves bass and speech")
		audioCommand = []string{"-strict", "experimental", "-b:a", "192k", "-af", "pan=stereo|FL<FL+SL+FC+LFE|FR<FR+SR+FC+LFE"}
	} else {
		log.Println("Using `-ac 2` due to unexpected channel layout:", audioStream.Channel_layout)
		audioCommand = []string{"-strict", "experimental", "-b:a", "192k", "-ac", "2"}  
	}
	videoStream := videoStreams[0]
	deinterlace := needsDeinterlacingFromFile(inPath)
	scaleAndCrop := needsScaleCrop1080FromFile(inPath)
	isIncompatible := isIncompatiblePixelFormat(videoStream.Pix_fmt)
	var videoArgs []string
	if videoStream.Codec_name == "h264" && videoStream.Codec_tag_string != "avc1" && !isIncompatible && !deinterlace && !scaleAndCrop {
		log.Println("Eligible for video not being transcoded, so no quality loss :)")
		videoArgs = []string{"-vcodec", "copy"}
	} else {
		log.Println("Video not eligible for muxing without transcoding.")
		if isIncompatible {
			log.Println("Video needs pixel format conversion")
			videoArgs = append(videoArgs, "-pix_fmt", "yuv420p")
		}
		if deinterlace {
			log.Println("Video is to be deinterlaced")
			videoArgs = append(videoArgs, "-vf", "yadif")
		}
		if scaleAndCrop {
			log.Println("Scale+crop to 1080p")
			videoArgs = append(videoArgs, "-vf", "scale=-1:1080,crop=1920:1080")
		}
	}
	return runConvertToHLS(inPath, outPath, audioStream.Index, videoStream.Index, audioCommand, videoArgs)
}
func isIncompatiblePixelFormat(pf string) bool {
	return strings.HasSuffix(pf, "9le") || strings.HasSuffix(pf, "9be") ||
		strings.HasSuffix(pf, "10le") || strings.HasSuffix(pf, "10be") ||
		strings.HasSuffix(pf, "12le") || strings.HasSuffix(pf, "12be") ||
		strings.HasSuffix(pf, "14le") || strings.HasSuffix(pf, "14be")
}