github.com/0chain/gosdk@v1.17.11/zboxcore/sdk/live_upload_reader_ffmpeg_windows.go (about)

     1  package sdk
     2  
     3  import (
     4  	"bufio"
     5  	"bytes"
     6  	"io"
     7  	"os/exec"
     8  	"strconv"
     9  	"strings"
    10  )
    11  
    12  // buildFfmpegArgs build ffmpeg arguments for windows
    13  // http://4youngpadawans.com/stream-camera-video-and-audio-with-ffmpeg/
    14  // https://trac.ffmpeg.org/wiki/DirectShow
    15  
    16  func buildFfmpegArgs(fileName string, delay int) []string {
    17  
    18  	if strings.HasSuffix(fileName, ".m3u8") {
    19  		return []string{
    20  			"-f", "dshow",
    21  			"-i", getInputDevices(),
    22  			"-preset", "ultrafast",
    23  			"-tune", "zerolatency",
    24  			"-vcodec", "libx264",
    25  			"-acodec", "aac",
    26  			"-ac", "2",
    27  			"-map", "0",
    28  			"-hls_time", strconv.Itoa(delay),
    29  
    30  			fileName,
    31  		}
    32  	}
    33  
    34  	//-f dshow -i video=0:audio=0 -preset ultrafast -tune zerolatency -vcodec libx264 -acodec aac -ac 2 -map 0 -f segment -segment_time 5  f:\zbox\live%d.mp4
    35  	return []string{
    36  		"-f", "dshow",
    37  		"-i", getInputDevices(),
    38  		"-preset", "ultrafast",
    39  		"-tune", "zerolatency",
    40  		"-vcodec", "libx264",
    41  		"-acodec", "aac",
    42  		"-ac", "2",
    43  		"-map", "0",
    44  		"-f", "segment",
    45  		"-segment_time", strconv.Itoa(delay),
    46  
    47  		fileName,
    48  	}
    49  }
    50  
    51  var (
    52  	inputDevices = ""
    53  )
    54  
    55  func getInputDevices() string {
    56  
    57  	if inputDevices != "" {
    58  		return inputDevices
    59  	}
    60  
    61  	cmd := exec.Command("ffmpeg", "-list_devices", "true", "-f", "dshow", "-i", "dummy")
    62  	defer func() {
    63  		if cmd != nil && cmd.Process != nil {
    64  			cmd.Process.Kill()
    65  
    66  		}
    67  	}()
    68  	// ffmpeg -list_devices true -f dshow -i dummy
    69  	// ffmpeg version 4.4-essentials_build-www.gyan.dev Copyright (c) 2000-2021 the FFmpeg developers
    70  	//   built with gcc 10.2.0 (Rev6, Built by MSYS2 project)
    71  	//   configuration: --enable-gpl --enable-version3 --enable-static --disable-w32threads --disable-autodetect --enable-fontconfig --enable-iconv --enable-gnutls --enable-libxml2 --enable-gmp --enable-lzma --enable-zlib --enable-libsrt --enable-libssh --enable-libzmq --enable-avisynth --enable-sdl2 --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxvid --enable-libaom --enable-libopenjpeg --enable-libvpx --enable-libass --enable-libfreetype --enable-libfribidi --enable-libvidstab --enable-libvmaf --enable-libzimg --enable-amf --enable-cuda-llvm --enable-cuvid --enable-ffnvcodec --enable-nvdec --enable-nvenc --enable-d3d11va --enable-dxva2 --enable-libmfx --enable-libgme --enable-libopenmpt --enable-libopencore-amrwb --enable-libmp3lame --enable-libtheora --enable-libvo-amrwbenc --enable-libgsm --enable-libopencore-amrnb --enable-libopus --enable-libspeex --enable-libvorbis --enable-librubberband
    72  	//   libavutil      56. 70.100 / 56. 70.100
    73  	//   libavcodec     58.134.100 / 58.134.100
    74  	//   libavformat    58. 76.100 / 58. 76.100
    75  	//   libavdevice    58. 13.100 / 58. 13.100
    76  	//   libavfilter     7.110.100 /  7.110.100
    77  	//   libswscale      5.  9.100 /  5.  9.100
    78  	//   libswresample   3.  9.100 /  3.  9.100
    79  	//   libpostproc    55.  9.100 / 55.  9.100
    80  	// [dshow @ 000001c224f0dd40] DirectShow video devices (some may be both video and audio devices)
    81  	// [dshow @ 000001c224f0dd40]  "Integrated Camera"
    82  	// [dshow @ 000001c224f0dd40]     Alternative name "@device_pnp_\\?\usb#vid_04ca&pid_7058&mi_00#6&24bef87c&0&0000#{65e8773d-8f56-11d0-a3b9-00a0c9223196}\global"
    83  	// [dshow @ 000001c224f0dd40] DirectShow audio devices
    84  	// [dshow @ 000001c224f0dd40]  "麦克风阵列 (Realtek High Definition Audio)"
    85  	// [dshow @ 000001c224f0dd40]     Alternative name "@device_cm_{33D9A762-90C8-11D0-BD43-00A0C911CE86}\wave_{2E8471BE-F843-412E-9E92-7C0E9E51E929}"
    86  	// dummy: Immediate exit requested
    87  
    88  	var reader io.Reader
    89  
    90  	var bufOutput, bufErr bytes.Buffer
    91  	cmd.Stderr = &bufErr
    92  	cmd.Stdout = &bufOutput
    93  
    94  	err := cmd.Run()
    95  	if err != nil {
    96  		reader = &bufErr
    97  	} else {
    98  		reader = &bufOutput
    99  	}
   100  
   101  	scanner := bufio.NewScanner(reader)
   102  
   103  	readVedioDeviceName := false
   104  	readAudioDeviceName := false
   105  
   106  	videoDeviceName := ""
   107  	audioDeviceName := ""
   108  
   109  	for scanner.Scan() {
   110  
   111  		if videoDeviceName != "" && audioDeviceName != "" {
   112  			break
   113  		}
   114  
   115  		line := scanner.Text()
   116  
   117  		if readVedioDeviceName && videoDeviceName == "" {
   118  			items := strings.Split(line, "\"")
   119  			if len(items) > 1 {
   120  				videoDeviceName = strings.TrimSpace(items[1])
   121  			}
   122  		}
   123  
   124  		if readAudioDeviceName && audioDeviceName == "" {
   125  			items := strings.Split(line, "\"")
   126  			if len(items) > 1 {
   127  				audioDeviceName = strings.TrimSpace(items[1])
   128  			}
   129  		}
   130  
   131  		if strings.Contains(line, "DirectShow video devices") {
   132  			readVedioDeviceName = true
   133  		}
   134  
   135  		if strings.Contains(line, "DirectShow audio devices") {
   136  			readAudioDeviceName = true
   137  		}
   138  
   139  	}
   140  
   141  	inputDevices = "video=" + videoDeviceName + ":audio=" + audioDeviceName + ""
   142  
   143  	return inputDevices
   144  }