Summary of ffmpeg usage

Keywords: encoding Lambda Python

Download and install

Download address

Executable files and dynamic libraries are provided, and Architecture version is used for pure command line.

View the currently available video and recording devices

Use the following command to view the device list

ffmpeg -list_devices true -f dshow -i dummy

The device name can be extracted from the output and used for video recording.

[dshow @ 0000023a33b3a680] DirectShow video devices (some may be both video and audio devices)
[dshow @ 0000023a33b3a680]  "USB 2.0 Webcam Device"
[dshow @ 0000023a33b3a680]     Alternative name "@device_pnp_\\?xxxx}\global"
[dshow @ 0000023a33b3a680]  "screen-capture-recorder"
[dshow @ 0000023a33b3a680]     Alternative name "@device_sw_{xxx}"
[dshow @ 0000023a33b3a680] DirectShow audio devices
[dshow @ 0000023a33b3a680]  "Microphone (Realtek High Definition Audio)"
[dshow @ 0000023a33b3a680]     Alternative name "@device_cm_{xxx}"
[dshow @ 0000023a33b3a680]  "virtual-audio-capturer"
[dshow @ 0000023a33b3a680]     Alternative name "@device_sw_{xxxx}"

Among them, "screen-capture-recorder" and "virtual-audio-capturer" are two virtual devices, which are used to assist in recording screen and sound card (download address).[ https://sourceforge.net/projects/screencapturer/files/].

To view the available configurations of a single device, you can use the following commands

ffmpeg -list_options true -f dshow -i video="{Name of Video Equipment}"

Available resolution of the camera can be obtained from the output

[dshow @ 000001d59c14a680] DirectShow video device options (from video devices)
[dshow @ 000001d59c14a680]  Pin "capture" (alternative pin name "0")
[dshow @ 000001d59c14a680]   pixel_format=yuyv422  min s=640x480 fps=5 max s=640x480 fps=30
[dshow @ 000001d59c14a680]   pixel_format=yuyv422  min s=640x480 fps=5 max s=640x480 fps=30
...
[dshow @ 000001d59c14a680]   pixel_format=yuyv422  min s=1280x720 fps=5 max s=1280x720 fps=10
[dshow @ 000001d59c14a680]   vcodec=mjpeg  min s=640x480 fps=5 max s=640x480 fps=30
[dshow @ 000001d59c14a680]   vcodec=mjpeg  min s=640x480 fps=5 max s=640x480 fps=30
...
[dshow @ 000001d59c14a680]   vcodec=mjpeg  min s=1280x720 fps=5 max s=1280x720 fps=30
2018-03-19 13:39:48,178 - video=USB 2.0 Webcam Device: Immediate exit requested

Getting Desktop Information

ffmpeg -list_options true -f gdigrab -i desktop

Desktop resolution can be extracted from output

[gdigrab @ 000001f1b84da680] Capturing whole desktop as 1920x1080x32 at (0,0)

python code extracts device list and configuration information

A Self-encapsulated function to obtain a list of available resolutions for devices

__author__ = "Dalton Xiong"
__license__ = "GPL"
__version__ = "0.1"
__email__ = "daltonxiong@gmail.com"
'''
//Reading the List of Video Recording Devices with ffmpeg and Its Supported Resolution
'''


import subprocess
import re
import logging
from collections import namedtuple

import parse

logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(message)s')

# Read device list, ignore ffmpeg's plug-in program for recording screen and recording card
def device_list():
    cmd = 'ffmpeg -list_devices true -f dshow -i dummy'
    logging.info('Read device list>>>>>>')
    logging.info(cmd)

    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = process.stdout.read()
    lines = str(output, encoding='utf-8').split('\n')

    video_device_list = []
    audio_device_list = []
    video_device_name_flag = False
    audio_device_name_flag = False
    for l in lines:
        logging.info(l)
        l = l.strip()
        if '[dshow' in l:
            if 'DirectShow video devices' in l:
                video_device_name_flag = True
                audio_device_name_flag = False
            elif 'DirectShow audio devices' in l:
                video_device_name_flag = False
                audio_device_name_flag = True
            elif video_device_name_flag and 'Alternative name' not in l:
                video_device_name = re.search(r'\"(.*)\"', l) or None
                video_device_name = video_device_name and video_device_name.groups()[0]
                if video_device_name != 'screen-capture-recorder': # Ignore Screen Recording Programs
                    video_device_list.append(video_device_name)
            elif audio_device_name_flag and 'Alternative name' not in l:
                audio_device_name = re.search(r'\"(.*)\"', l) or None
                audio_device_name = audio_device_name and audio_device_name.groups()[0]
                if audio_device_name != 'virtual-audio-capturer': # Ignore Sound Card Recording Procedure
                    audio_device_list.append(audio_device_name)

    return video_device_list, audio_device_list

# Information of image acquisition equipment
def video_device_info(device_name):
    cmd = 'ffmpeg -list_options true -f dshow -i video="{}"'.format(device_name)
    logging.info('Read image acquisition equipment({})Information>>>>>>'.format(device_name))
    logging.info(cmd)

    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = process.stdout.read()
    lines = str(output, encoding='utf-8').split('\n')

    pixel_format_set = set()
    vcodec_set = set()
    for l in lines:
        logging.info(l)
        l = l.strip()
        if '[dshow' not in l:
            continue

        if 'pixel_format' in l:
            result = parse.parse('{}   pixel_format={}  min s={} fps={} max s={}x{} fps={}', l)
            if result:
                pixel_format_set.add( (result[1], result[4], result[5], result[6]) )
        elif 'vcodec' in l:
            result = parse.parse('{}   vcodec={}  min s={} fps={} max s={}x{} fps={}', l)
            if result:
                vcodec_set.add( (result[1], result[4], result[5], result[6]) )
        else:
            continue

    return pixel_format_set, vcodec_set

# Sound Acquisition Equipment Information
def audio_device_info(device_name):
    cmd = 'ffmpeg -list_options true -f dshow -i audio="{}"'.format(device_name)
    logging.info('Read Sound Acquisition Equipment({})Information>>>>>>'.format(device_name))
    logging.info(cmd)

    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = process.stdout.read()
    lines = str(output, encoding='utf-8').split('\n')

    format_set = set()
    for l in lines:
        logging.info(l)
        l = l.strip()
        if '[dshow' not in l:
            continue

        result = parse.parse('{}   min ch={} bits={} rate= {} max ch={} bits={} rate= {}', l)
        if result:
            format_set.add((result[4], result[5], result[6]))

    return format_set

# Desktop resolution size
def desktop_device_info():
    cmd = 'ffmpeg -list_options true -f gdigrab -i desktop'
    logging.info('Read desktop image information>>>>>>')
    logging.info(cmd)

    process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    output = process.stdout.read()
    lines = str(output, encoding='utf-8').split('\n')

    format_set = set()
    for l in lines:
        logging.info(l)
        l = l.strip()

        if '[gdigrab' not in l:
            continue

        result = parse.parse('{} Capturing whole desktop as {}x{}x{} at (0,0)', l)
        if result:
            format_set.add( (result[1], result[2]) )

    return format_set

# Get a list of all devices and available configuration information
def device_config_list():
    video_device_list, audio_device_list = device_list()

    # Video equipment
    VideoDeviceInfo = namedtuple('VideoDeviceInfo', ['width', 'height', 'fps'])
    vdevice_list = []
    for device_name in video_device_list:
        pixel_format_set, vcodec_set = video_device_info(device_name)
        format_set = vcodec_set or pixel_format_set
        format_list = set()
        for (format, width, height, fps) in format_set:
            format_list.add( VideoDeviceInfo(width=int(width), height=int(height), fps=int(fps)) )

        format_list = list(format_list)
        format_list.sort(key=lambda x: (x.fps, x.width), reverse=True)

        device_info = {'name': device_name, 'format_list': format_list}
        vdevice_list.append(device_info)

    # The recording equipment
    AudioDeviceInfo = namedtuple('AudioDeviceInfo', ['channel', 'bits', 'rate'])
    adevice_list = []
    for device_name in audio_device_list:
        format_set = audio_device_info(device_name)
        format_list = set()
        for (channel, bits, rate) in format_set:
            format_list.add( AudioDeviceInfo(channel=int(channel), bits=int(bits), rate=int(rate)) )

        format_list = list(format_list)
        format_list.sort(key=lambda x: (x.channel, x.bits), reverse=True)

        device_info = {'name': device_name, 'format_list': format_list}
        adevice_list.append(device_info)

    # Computer Desktop
    desktop_format_set =  desktop_device_info()
    if len(desktop_format_set) != 1:
        raise ValueError('Screen Resolution Reading Failed')

    desktop_format_set = list(desktop_format_set)[0]
    DesktopDeviceInfo = namedtuple('DesktopDeviceInfo', ['width', 'height'])
    desktop_info = DesktopDeviceInfo(width=int(desktop_format_set[0]), height=int(desktop_format_set[1]))

    logging.info('The list of video recorders and available configurations are as follows:')
    logging.info('{}'.format(vdevice_list))

    logging.info('The list of recording devices and available configurations are as follows:')
    logging.info('{}'.format(adevice_list))

    logging.info('The desktop resolution is:{}x{}'.format(desktop_info.width, desktop_info.height))

    return vdevice_list,adevice_list,desktop_info

if __name__ == '__main__':
    vdevice_list, adevice_list, desktop_info = device_config_list()

Encapsulated a function device_config_list returned, a list of recording devices, a list of recording devices, desktop resolution

The list of video recorders and available configurations are as follows:
[{'name': 'USB 2.0 Webcam Device', 'format_list': [VideoDeviceInfo(width=1280, height=720, fps=30), VideoDeviceInfo(width=960, height=540, fps=30), VideoDeviceInfo(width=848, height=480, fps=30), VideoDeviceInfo(width=640, height=360, fps=30), VideoDeviceInfo(width=640, height=480, fps=30), VideoDeviceInfo(width=424, height=240, fps=30), VideoDeviceInfo(width=352, height=288, fps=30), VideoDeviceInfo(width=320, height=240, fps=30), VideoDeviceInfo(width=320, height=180, fps=30), VideoDeviceInfo(width=176, height=144, fps=30), VideoDeviceInfo(width=160, height=120, fps=30)]}]
The list of recording devices and available configurations are as follows:
[{name':'Realtek High Definition Audio','format_list': [Audio DeviceInfo (channel = 2, bits = 16, rate = 44100)]]
Desktop resolution: 1920x1080

Acquisition cameras and desktops and microphones

Effect 1

Without changing the resolution of the desktop and camera, the two pictures can be displayed side by side by hstack. The hstack function requires that the height of the two pictures must be consistent, so the pad function is added to fill the high-short pictures with pure color.

The code is commented in sections as follows

ffmpeg 
-f gdigrab -i desktop  # Input Desktop Screen
-f dshow -i video="USB 2.0 Webcam Device" -s 1280*720  # Input camera screen
-filter_complex "[0:v]scale=360:-1,pad=1920:1080:0:0:black[left];[1:v]scale=360:-1,pad=1280:1080:0:0:black[right];[left][right]hstack"  #Filter operation
-f dshow -i audio="Microphone (Realtek High Definition Audio)"   # Input microphone
-y out.mp4  # output to a file

Posted by mrMarcus on Sun, 19 May 2019 18:42:48 -0700