{"id":13613694,"url":"https://github.com/luziferius/av1transcoder","last_synced_at":"2025-07-28T15:12:04.842Z","repository":{"id":57413014,"uuid":"224695157","full_name":"luziferius/av1transcoder","owner":"luziferius","description":"Transcode video files to the AV1 format using ffmpeg and libaom-av1.","archived":false,"fork":false,"pushed_at":"2021-06-11T09:54:58.000Z","size":130,"stargazers_count":6,"open_issues_count":4,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-28T05:51:09.262Z","etag":null,"topics":["av1-codec","ffmpeg-wrapper","python3","transcoding","video-transcoding"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/luziferius.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGES","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-11-28T16:48:11.000Z","updated_at":"2024-06-14T18:59:57.000Z","dependencies_parsed_at":"2022-08-29T15:23:34.350Z","dependency_job_id":null,"html_url":"https://github.com/luziferius/av1transcoder","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luziferius%2Fav1transcoder","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luziferius%2Fav1transcoder/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luziferius%2Fav1transcoder/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luziferius%2Fav1transcoder/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/luziferius","download_url":"https://codeload.github.com/luziferius/av1transcoder/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248923724,"owners_count":21183953,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["av1-codec","ffmpeg-wrapper","python3","transcoding","video-transcoding"],"created_at":"2024-08-01T20:00:52.712Z","updated_at":"2025-04-14T17:20:26.500Z","avatar_url":"https://github.com/luziferius.png","language":"Python","readme":"av1transcoder\n=============\n\nEncode AV1 videos with ffmpeg and libaom-av1.\n\nThis tool takes input videos and encodes them to AV1, using the libaom-av1 encoder.\nAt the time of writing this, the reference encoder is still very slow and can’t fully utilize modern multi-core CPUs.\nTo mitigate this issue, this program splits the input at scene cuts and encodes multiple scenes in parallel,\nallowing full CPU utilization and therefore faster encode times.\n\nThis is a command line application only. There is no GUI.\n\nHow is the overall encoding process done?\n-----------------------------------------\n\nThis program takes multiple passes over each input file:\n\n1. First, it uses the ffmpeg scene cut filter to determine the scene cuts.\n   This is done to avoid splitting the video in the middle of a scene,\n   because such a split causes an artificial and unnecessary bitrate spike.\n2. It then merges all short scenes below the minimum length threshold,\n   so that the overall scene length falls between some acceptable lower and upper bound.\n   (Beware: Upper bounds are currently not implemented!)\n3. It will then start an ffmpeg instance for each found scene, encoding the scenes independently in parallel.\n   Only a limited, configurable number of instances will run at any time to not overload the system.\n   Each running scene encoding will be performed outputting into a temporary directory,\n   and moved into a central scene repository directory on completion.\n   This ensures that only completed scene encodes are kept, making the process fully stoppable and resumable at any time.\n   Incomplete and aborted or otherwise failing encodes will be thrown away.\n\n   On resume, the program picks up any finished work, like finished\n   scenes in the scene repository and skips redoing them, thus avoiding duplicate work.\n\n4. When all scenes are encoded, the ffmpeg ``concat`` demuxer is used to join all scenes into a single video file.\n\n\nRequirements\n------------\n\n- Python \u003e= 3.7 (3.6 may work, but is untested)\n- recent ffmpeg with recent and enabled libaom-av1\n  (git master builds from around November 2019 for both ffmpeg and libaom-av1 work.)\n- (A somewhat fast CPU and some gigabytes of free and writable disk space.\n  The encoding process requires about the size of the final result for temporary data during the encoding process.)\n\n\nInstall\n-------\n\nInstall from PyPI using :code:`pip3 install av1transcoder`\n\nAlternatively, to install the latest version from a local repository checkout,\nopen a terminal at the root level of your checkout (contains ``setup.py`` and this README) and run:\n:code:`pip3 install .` (Note the dot indicating the current directory).\n\nAs a third alternative, you can run the program directly from the repository checkout without installation.\nThe repository contains a simple runner script (named ``av1transcoder-runner.py``) that can be used for this purpose.\n\nCurrently, there is no setup.exe or directly executable Python bundle for Windows platforms.\n\nUsage\n-----\n\nExecute :code:`av1transcoder` after installation or run :code:`./av1transcoder-runner.py` from the source tree,\nif you have cloned the development repository.\nThe program expects one or more video files as positional arguments. Each given video file will be transcoded to AV1.\nThe encoding process can be controlled using several optional command line switches.\nUse the ``--help`` switch to view all possible parameters with explanations. A copy of the output is included below.\nPlease read the notes about limitations and issues below (See point \"Important notes\")!\n\nFull ``--help`` output\n++++++++++++++++++++++\n\nFor reference, here is the ``--help`` output:\n\n::\n\n  $ av1transcoder -h\n    usage: av1transcoder [-h] [-o OUTPUT_DIR] [-t TEMP_DIR] [-k] [-f] [-s SCENE_CUT_THRESHOLD] [-m SECONDS] [-1]\n                               [--crop TOP BOTTOM LEFT RIGHT] [-e STRING] [-g STRING]\n                               [-c MAX_CONCURRENT_ENCODES] [--dump-commands {yes,no,only}] [--deinterlace]\n                               [-L NUMBER] [-v] [-V] [--cutelog-integration] [--ffmpeg EXECUTABLE_NAME]\n                               [--ffprobe EXECUTABLE_NAME] [--ffmpeg-base DIRECTORY]\n                               input_file [input_file ...]\n\n    Transcode video files to AV1. This program takes input video files and transcodes the video track to the AV1 format\n    using the libaom-av1 reference encoder.\n\n    positional arguments:\n      input_file            Input video files. All given video files will be transcoded to AV1.\n\n    optional arguments:\n      -h, --help            show this help message and exit\n      -o OUTPUT_DIR, --output-dir OUTPUT_DIR\n                            Store the result in this directory. If set and --temp-dir is unset, also store the temporary\n                            data here. If unset, results are stored alongside the input file.\n      -t TEMP_DIR, --temp-dir TEMP_DIR\n                            Store temporary data in this directory. If unset, use the output directory set by --output-\n                            dir. If that is unset, store the temporary data alongside the input data.\n      -k, --keep-temp       Keep temporary data after the transcoding process finished. May help in resolving transcoding\n                            issues.\n      -f, --force-overwrite\n                            Force overwriting existing data. If unset and filename collisions are detected, the affected\n                            input files are skipped. If set, existing files will be overwritten.\n      -s SCENE_CUT_THRESHOLD, --scene-cut-threshold SCENE_CUT_THRESHOLD\n                            Define the threshold value for the scene cut detection filter. Accepts a decimal number in\n                            the range (0,1]. Defaults to 0.300000\n      -m SECONDS, --min-scene-length SECONDS\n                            Minimal allowed scene duration in seconds. Adjacent detected scenes are combined to have at\n                            least this duration, if possible. This is not a hard limit. It prevents splitting the input\n                            video into many small and independent encoding tasks to improve encoding efficiency. Defaults\n                            to 30\n      -1, --single-pass     Use Single-Pass encoding instead of Two-Pass encoding. Various sources indicate that this is\n                            neither recommended for libaom-av1 nor saves much time compared to Two-Pass encoding.\n      --crop TOP BOTTOM LEFT RIGHT\n                            Crop the given number of pixels from the input videos. You can specify the option multiple\n                            times to give each input file their own individual crop parameters. If more input files are\n                            given than --crop instances, the last given set of crop values will be used for all remaining\n                            input files. BEWARE: This uses an ffmpeg video filter, thus is incompatible with additional\n                            custom video filters given using --encoder-parameters. Trying to use --crop and a custom\n                            video filter at the same time will cause ffmpeg to fail.\n      -e STRING, --encoder-parameters STRING\n                            Add custom encoder parameters to the encoding process. Add all parameters as a single, quoted\n                            string. These parameters will be passed directly to all ffmpeg processes doing the encoding\n                            work. As an example, the default value is '-pix_fmt yuv420p10le -cpu-used 4 -crf 15 -frame-\n                            parallel 0 -threads 1 -auto-alt-ref 1 -lag-in-frames 8 -enable-cdef 1 -enable-global-motion 1\n                            -enable-intrabc 1', which is tuned for high quality encodes of SD material, for example from\n                            DVD sources. BEWARE: Due to a bug in Python argument parser\n                            (https://bugs.python.org/issue9334), the parameters MUST NOT begin with a dash (-) when used\n                            as --encoder-parameters \"\u003cparameters\u003e\". You MUST begin the quoted custom parameter string\n                            with a space character or use = to specify the string, like --encoder-parameters=\"-your-\n                            parameters-here\".\n      -g STRING, --global-parameters STRING\n                            Add custom global parameters to all ffmpeg processes. These are passed in as the first\n                            arguments to ffmpeg before the input file and can be used to enable hardware acceleration or\n                            similar global switches. Example: '-hwaccel cuvid'. When using this to enable hardware\n                            decoding, ensure that the HW decoder can handle at least --max-concurrent-encodes parallel\n                            decoder instances. Default is to not add parameters at all, leaving everything at the default\n                            settings. BEWARE: The issue described for --encoder-parameters applies here, too.\n      -c MAX_CONCURRENT_ENCODES, --max-concurrent-encodes MAX_CONCURRENT_ENCODES\n                            Run up to this many ffmpeg instances in parallel. Takes a positive integer, defaults to 8\n      --dump-commands {yes,no,only}\n                            Dump executed ffmpeg commands in text files for later examination or manual execution. The\n                            files will be placed in the temporary directory. If set to 'only', this program will only\n                            dump the command lines but not actually execute encoding tasks. The scene detection will\n                            always be executed even if set to 'only', because the later steps require the data to be\n                            present. Defaults to 'no'. Setting to a non-default value implies setting '--keep-temp'.\n      --deinterlace         Deinterlace the interlaced input video using the yadif video filter. BEWARE: This uses an\n                            ffmpeg video filter, thus is incompatible with additional custom video filters given using\n                            --encoder-parameters. If you use custom video filters or require another deinterlacer, like\n                            IVTC, add the de-interlace filter to your filter chain instead of using this option.\n      -L NUMBER, --limit-encodes NUMBER\n                            Stop after encoding this number of scenes. Useful, if you plan to split the encoding process\n                            over multiple sessions. If given, this program will encode this NUMBER of previously not\n                            encoded scenes. Only if all scenes are finished, the final result will be assembled from\n                            scenes. Default is to not limit the number of encodes. For the sake of this option, the two\n                            encodes needed for a Two-Pass encode count as one encode towards this limit. For now, setting\n                            this option implies --keep-temp.\n      -v, --version         show program's version number and exit\n      -V, --verbose         Increase output verbosity. Also show debug messages on the standard output.\n      --cutelog-integration\n                            Connect to a running cutelog instance with default settings to display the full program log.\n                            See https://github.com/busimus/cutelog for details.\n      --ffmpeg EXECUTABLE_NAME\n                            Specify the ffmpeg executable name. Can be a relative or absolute path or a simple name (i.e.\n                            an executable name without path separators). If given a simple name, the system PATH variable\n                            will be searched. Defaults to \"ffmpeg\"\n      --ffprobe EXECUTABLE_NAME\n                            Specify the ffprobe executable name. Can be a relative or absolute path or a simple name\n                            (i.e. an executable name without path separators). If given a simple name, the system PATH\n                            variable will be searched. Defaults to \"ffprobe\"\n      --ffmpeg-base DIRECTORY\n                            Specify the path to a custom ffmpeg installation, for example \"/opt/ffmpeg/bin\". If given,\n                            both --ffmpeg and --ffprobe arguments are treated as a path relative to this path. Not set by\n                            default.\n\n    The resulting files are named like \u003cinput_file_name\u003e.AV1.mkv and are placed alongside the input file, or into the\n    output directory given by --output-dir. During the encoding process, each input file will have it’s own temporary\n    directory named \u003cinput_file_name_with_extension\u003e.temp. The temporary directory is placed according to the placement\n    rules, preferring --temp-dir over --output-dir over the input file’s directory. The output files will only contain\n    video tracks. You have to add back other tracks yourself, like audio or subtitles, and mux them into the container of\n    your choice. Files with multiple video tracks are untested and probably won’t work. File names that contain esoteric\n    characters like newlines will probably break the ffmpeg concat demuxer and will likely cause failures. Long arguments\n    can be abbreviated, as long as the abbreviation is unambiguous. Don’t use this feature in scripts, because new\n    argument switches might break previously valid abbreviations. Arguments can be loaded from files using the\n    @-Notation. Use \"@/path/to/file\" to load arguments from the specified file. The file must contain one argument per\n    line. It may be useful to load a set of common arguments from a file instead of typing them out on the command line,\n    when you can re-use the same set of arguments multiple times.\n\n\n\n\nImportant notes\n---------------\n\nDue to a bug in the Python argument parser module (https://bugs.python.org/issue9334),\nThe values given for ``--global-parameters`` and ``--encoder-parameters`` MUST NOT begin with a dash.\nFor example ``--encoder-parameters \"-pix_fmt yuv420p\"`` is NOT ALLOWED, and will cause an error during the parsing\nstep. This can’t be fixed from my side.\n\nBut since ffmpeg always begin with a dash, you’ll run into this issue.\nAs a workaround, begin the custom ffmpeg parameters with a space,\nfor example ``\" -pix_fmt yuv420p\"`` (note the space between ``\"`` and ``-``)\nor use ``=`` to join the option and it’s value like this:\n``--encoder-parameters=\"-cpu-used 3\"``\n\n\nCropping and de-interlacing\n+++++++++++++++++++++++++++\n\nSpecifying cropping parameters using ``--crop`` or using ``--deinterlace`` is incompatible with custom encoder\nsettings that contain ffmpeg video filters like ``-vf some_filter=values``.\nTrying to use both will result in ffmpeg complaining and aborting.\n\nIf you want to use a custom video filter, do not use the mentioned options.\nInstead add the filters to your custom filter chain as needed yourself.\n\n\nLoading arguments from files\n++++++++++++++++++++++++++++\n\nArguments for this program can be loaded from files.\nUse ``@/path/to/file`` as a parameter to load the parameters in the given file.\nIn the argument file, write one option per line. When setting paths,\nfor example for ``--temp-dir`` or ``--output-dir``, you do not need to put the path\nin quotation marks.\nFor best results (and long-term readability), use long style options and join the option and value with =, like:\n``--temp-dir=/path/to/temp/directory``\n\n\nTwo-Pass mode: Technical details\n++++++++++++++++++++++++++++++++\n\nTwo-Pass mode uses a simple scheduler to ensure high load throughout the encoding process, avoiding single, long running\nencoding processes remaining at the end of the encoding process and artificially delaying the whole process.\n\nThis is done by doing all first pass encodes first and then use the first pass log file size as simple metric to estimate\nthe second-pass runtime and schedule the second passes accordingly.\nThe used metric assumes that there is a linear correlation between first-pass log file size and second-pass encoding time.\nWhen the encoding tasks are sorted by the log file size and therefore by the assumed relative run time, the program will\nstart encoding long running scenes first. This will result in better multicore usage at the end of the processing.\nIt avoids starting long scenes, like the ending credits, at the end of the processs, and therefore lessens the impact of\na single, long encode delaying the whole process. With this scheduling approach, it is way more likely that the\nlast running encodings will be encoding short and easy scenes and therefore having less overall delay.\n\n\nAbout\n-----\n\nCopyright (C) 2019, Thomas Hess\n\nThis program is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.\nSee the LICENSE file for details.\n","funding_links":[],"categories":["HarmonyOS","Encoding"],"sub_categories":["Windows Manager","AV1"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluziferius%2Fav1transcoder","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fluziferius%2Fav1transcoder","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluziferius%2Fav1transcoder/lists"}