cytopia/ffscreencast

ffscreencast 2.0 rewrite and brainstorm proposal/discussion.

cytopia opened this issue · 3 comments

ffscreencast 2.0 rewrite and brainstorm

I have noticed that there are quite some limitations on the existing ffscreencast implementation,
some bugs that are hard to fix, options that are not as self-explanatory as I have hoped and
the code is currently hard to maintain.

That is the reason I will do a complete rewrite from scratch.

What must be done?

  1. Separate linux and osx versions for better maintainability
  2. Restructure command line arguments for easier usage
  3. Address current bugs
  4. Add more features (streaming, camera positions/resolutions, etc)

I will first work on the linux version ffscreencast-linux and once done start with osx ffscreencast-osx.
Furthermore I hope I can finally also get the BSD version done afterwards.

Get involved and give feedback

I will address features and commandline arguments below as far as I have thought them through.
Nothing is fix yet, so I rely on your feedback to suggest improvements.

The goal is to have a really easy-to-use command line version of a screen-recorder with many options
that are compatible with other GUI implementations.

So if you like this idea, do comment and let me know.

I want the rewrite to be completely thought through and planned, before I am going to start working
on it.

ffscreencast-linux proposal

Features

This is the current feature list that I have thought about. Let me know about anything else
you want to be added to the list.

  • record whole desktop, specific monitor, specific window or a selected area
  • specify to record cursor or not
  • have different audio input source (e.g.: pulse)
  • be able to align camera overlay to any desired position
  • be able to scale camera resolution overlay
  • scale output video during recording
  • output video to file or directly to a network stream

Command line options

This is a first draft showing the possible command line arguments:

1. Input arguments

1.1 Video
--ivideo source <string>        Either 'desktop', 'monitor', 'window', or 'area'
                                Defaults to 'desktop'

--ivideo monitor <int>          When using 'source monitor', specify the monitor
                                number to record.
                                Defaults to first found monitor

--ivideo frame <int>            Input video framerate.
                                Defaults to 30

--ivideo cursor <string>        Capture mouse cursor? 'yes' or 'no'.
                                Defaults to 'no'
1.2 Audio
--iaudio dev <int>              Will record audio with the given device number.
                                Defaults to first audio device found.
                                If this option is omitted, no audio will be recorded.

--iaudio format <string>        Audio input format (e.g.: alsa)

--iaudio source <string>        Audio input source (e.g.: pulse)

--iaudio channel <int>          Audio channels to record (e.g.: 1 or 2)
                                Defaults to 2
1.3 Camera
--icam dev <int>                Will enable camera overlay with the given camera device number.
                                Defaults to first camera device found.
                                If this option is omitted, no camera will be recorded.


--icam pos <string> <string>    Sets the camera position.
                                Supported values: <left|center|right> <top|center|bottom>
                                Defaults to 'right' 'bottom'

--icam pad <string>             Sets the camera padding from the nearest edge.
                                In case of 'center' it will pad from the right or bottom.
                                Format: --icam pad 10x10
                                Defaults to '0x0'

--icam res <string>             Scales the camera resultion to the supplied value.
                                Format:             --icam res "640x480"
                                Format keep height: --icam res "320x-1"
                                Format keep width : --icam res "-1x480"
                                Defaults to the highest supported camera resolution.

2. Output encoding

2.1 Video
--ovideo codec <string>         Video output format.
                                Defaults to 'libx264'

--ovideo res <string>           Scale down the output resolution.
                                Defaults to video input resolution.
                                Format:             --ovideo res 960x540
                                Format keep height: --ovideo res 960x-1
                                Format keep width:  --ovideo res -1x540

--ovideo args <string>          Additional output encoding arguments to pass to ffmpeg.
                                Defaults to: '-crf 20 -preset veryfast -minrate 150l -maxrate 500k'
2.2 Audio
--oaudio acodec <string>        Audio output format.
                                Defaults to 'libfaac'

--oaudio freq <int>             Audio frequency.
                                Defaults to 44100

--oaudio bitrate <int>          Audio bitrate.
                                Defaults to 96000

3. Output

--output type <sting>           Output to file or to network stream.
                                Values: 'file' or 'stream'
                                Defaults to 'file'

--output container <string>     Output container format to use.
                                Defaults to 'mkv'

--output file <string>          Output file.
                                Defaults to ~/Desktop/ScreenCast-YY-mm-dd__HH-mm-ss.ext
                                Only applicable when output type == file

--output stream-proto <string>  Stream output protocol to stream to.
                                Values: 'tcp' or 'udp'.
                                Only applicable when output type == stream

--output stream-addr <string>   Stream output IP address or hostname to stream to.
                                Format: --output stream-addr 192.168.0.1
                                Format: --output stream-addr host1.example.tld
                                Only applicable when output type == stream


--output stream-port <int>      Stream output port to stream to.
                                Format: --output stream-port 5891

--output stream-meta <string>   Stream metadata to include in stream.
                                Example: 'streamName=my-twich-channel'

4. Config arguments

--config <string>               Specify to load configuration from config file instead of
                                having to specify them via command line arguments.
                                Default config with default argument values will be in
                                ~/.config/ffscreencast/default.conf
                                Let's you easily create multiple configs for different occasions:
                                ffscreencast --config ~/.config/ffscreencast/twitch-stream.conf
                                ffscreencast --config ~/.config/ffscreencast/grab-desktop.conf

5. Misc arguments

I will also include the current arguments for:

--dry                           Show ffmpeg command from specified options
--list                          List all monitor, audio and camera devices
--slist                         List monitor devices
--alist                         List audio devices
--clist                         List camera devices

Hi,

I just saw your script, it's nice. I did a similar script but it's really basic, only for casual usage.

After read your code, I thing that a better way to read arguments is something like:

    while getopts f: option
    do
	case "${option}" in
            f) FILE=${OPTARG}   ;;
	esac
    done

Which branch are you using for this topic?

There is no branch available yet. I can create a long living feature branch if you want to do some work and help out on the rewrite.

Sounds silly, rather than break apart linux / mac installations, have you considered using something like nodejs which can handle this cross platform with process.platform and it'll become more readable and maintain-able code overall (scalable most importantly). you can use something like yargs to parse the arguments and child_process to spawn all the processes. Nodejs also has a very nice piping mechanism you could use to write to file or server or any output you like. You could also look at js-ffmpeg for some inspiration. Also you can make this into an npm package and that's very easy to install, also you would have a package versioning system too.