{"id":18982305,"url":"https://github.com/profusion/pf-video-transcribe","last_synced_at":"2026-06-19T08:32:08.121Z","repository":{"id":170679511,"uuid":"646881196","full_name":"profusion/pf-video-transcribe","owner":"profusion","description":"Transcribe videos and create html pages with that","archived":false,"fork":false,"pushed_at":"2023-05-29T21:20:24.000Z","size":57,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":16,"default_branch":"main","last_synced_at":"2025-11-11T08:03:03.052Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/profusion.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-29T14:50:39.000Z","updated_at":"2024-06-08T01:05:41.000Z","dependencies_parsed_at":null,"dependency_job_id":"ed5516e7-c29f-4f67-8f9f-5d720e70effe","html_url":"https://github.com/profusion/pf-video-transcribe","commit_stats":null,"previous_names":["profusion/pf-video-transcribe"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/profusion/pf-video-transcribe","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/profusion%2Fpf-video-transcribe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/profusion%2Fpf-video-transcribe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/profusion%2Fpf-video-transcribe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/profusion%2Fpf-video-transcribe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/profusion","download_url":"https://codeload.github.com/profusion/pf-video-transcribe/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/profusion%2Fpf-video-transcribe/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34523982,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-19T02:00:06.005Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-11-08T16:13:05.088Z","updated_at":"2026-06-19T08:32:08.105Z","avatar_url":"https://github.com/profusion.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"ProFUSION Video Transcribe\n==========================\n\nInstall\n-------\n\nInstall the project using `Poetry \u003chttps://python-poetry.org/docs/#installation\u003e`_:\n\n.. code-block:: console\n\n    $ poetry install --with dev\n    Installing dependencies from lock file\n    ...\n    Installing the current project: pf-video-transcribe\n\nThis project uses `Faster Whisper \u003chttps://pypi.org/project/faster-whisper/\u003e`_,\na faster implementation of `OpenAI's Whisper \u003chttps://openai.com/research/whisper\u003e`_,\nwhich in turn is built on top of `CTranslate2 \u003chttps://opennmt.net/CTranslate2/index.html\u003e`_\nhardware optimizations, that requires installation of **NVidia CUDA libraries**, see\n`their installation instructions \u003chttps://opennmt.net/CTranslate2/installation.html\u003e`_.\n\nRun\n---\n\nRun the command line tool:\n\n.. code-block:: console\n\n    $ pf-video-transcribe --help\n\nAll commands take ``--log=LEVEL`` or ``--log=DOMAIN:LEVEL`` to change the\nlog level of every package, such as ``pf_video_transcribe.transcribe``,\n``faster_whisper`` and so on. If no domain is given, then the provided level\napplies to all log domains. This is a global option and should be specified\nbefore the subcommand.\n\nSubcommands are explained in the next sections.\n\nTranscription\n=============\n\nGiven that the transcription is a heavy process and takes a lot to load the model\nand then to process each media file, it's implemented as a batch operation that\ngenerates an intermediate in the `JSON Lines \u003chttps://jsonlines.org/\u003e`_\n(``\".jsonl\"``) format, with a ``\"header\"`` line followed by all the ``\"segment\"``,\nended by a ``\"finished\"`` line with success or failure indicator. Each ``segment``\ncarries the useful information extracted by\n`OpenAI Whisper \u003chttps://github.com/openai/whisper\u003e`_:\n\n.. code-block:: console\n\n    $ pf-video-transcribe transcribe videos/my-video.mp4 videos/other-video.mp4\n\n\nThis will generate ``videos/my-video.jsonl`` and ``videos/other-video.jsonl``.\n\nNote that the first time it will take a lot to download the model from the internet.\nIn the next iterations, the local model will be used, but first they will be checked\nremotely -- which can also take time. Using the ``--local`` flag will skip that check.\n\nThe language is auto-detected from the first 30 seconds of actual sound (silent is\nignored), but if you do know the language, use the ``--language=LANG`` flag.\n\nAudio Speech Recognition (ASR) models work on slices of the media, producing segments\nthat are smaller than an actual human language sentence/phrase.\nThe ``--merge-threshold=SECONDS`` will merge sibling segments if:\n``next_segment.start - last_segment.end \u003c= merge_threshold``. The default is 1 second.\n\nA more complex example:\n\n.. code-block:: console\n\n    $ pf-video-transcribe \\\n          --log=DEBUG \\\n          transcribe \\\n          --local \\\n          --language=pt \\\n          --merge-threshold=5 \\\n          videos/my-video.mp4 videos/other-video.mp4\n\nWith the transcribed ``\".jsonl\"`` one can convert to more usable formats,\nsee the next sections.\n\n\nConvert to HTML\n===============\n\nThis generates the HTML meant to easy viewing of the result, a ``\u003cvideo\u003e`` linking\nto the transcribed media alongside a ``\u003ctrack kind=\"subtitles\"\u003e`` linking to the\nsubtitles, the thumbnail to be used by `OpenGraph \u003chttps://ogp.me/\u003e`_ ``og:image``\nand the actual transcription segments.\n\nNote: both ``.vtt`` (subtitles) and ``.jpeg`` (thumbnail) are auto-generated\nif they don't exist or if they are older than the actual input ``.jsonl``.\n\n\nConvert to VTT\n==============\n\nWeb Video Text Track is a subtitle specified by the\n`W3C \u003chttps://w3c.github.io/webvtt/\u003e`_ and used by all web browsers whenever\nspecified inside the ``\u003cvideo\u003e`` element.\n\nThe conversion takes parameter ``--duration-threshold=SECONDS`` to control the maximum\nduration of a single subtitle entry.\n\n.. code-block:: console\n\n    $ pf-video-transcribe vtt videos/*.jsonl\n\n\nConvert to SRT\n==============\n\nSRT or SubRip is a defacto standard subtitle format that most media players will take.\nThe conversion takes parameter ``--duration-threshold=SECONDS`` to control the maximum\nduration of a single subtitle entry.\n\n.. code-block:: console\n\n    $ pf-video-transcribe srt videos/*.jsonl\n\n\nCreate Thumbnail\n================\n\nUses `FFmpeg \u003chttps://ffmpeg.org/\u003e`_ to generate a thumbnail from the video or\nits transcription. The ``--size=WIDTHxHEIGHT`` allows to override the default\n``320x-1`` (-1 is used to calculate that dimension from the other, keeping the\naspect ratio).\n\n.. code-block:: console\n\n    $ pf-video-transcribe thumbnail videos/*.jsonl\n\n\nCreating Index HTML\n===================\n\nRecursively scans the given directories looking for ``.html`` files, which\ncan be produced by this tool or not. The generated index will take the ``\u003ctitle\u003e``\nand ``\u003cmeta property=\"og:image\"\u003e`` to gather the actual title or preview.\n\nIt's a very simple way to generate a landing page.\n\n.. code-block:: console\n\n    $ pf-video-transcribe index_html videos/\n\n\nServing (Development)\n=====================\n\nWhile developing this tool or playing with parameters it's useful to serve\nthe files from ``http://`` as the ``file://`` will have some issues with\nvideo files (security limitations). By default serves at ``--port=8000``.\n\n.. code-block:: console\n\n    $ pf-video-transcribe serve videos/\n\n\nDevelopment\n-----------\n\nInstall the project with development dependencies:\n\n.. code-block:: console\n\n    $ poetry install --with dev\n    Installing dependencies from lock file\n    ...\n    Installing the current project: pf-video-transcribe\n\n\nInstall `pre-commit \u003chttps://pre-commit.com/\u003e`_ in your machine, then install the GIT Hooks:\n\n.. code-block:: console\n\n    $ pre-commit install\n    pre-commit installed at .git/hooks/pre-commit\n    pre-commit installed at .git/hooks/pre-push\n    pre-commit installed at .git/hooks/pre-merge-commit\n\n\nUsed tools:\n\n* Code Formatter: `Black \u003chttps://black.readthedocs.io/\u003e`_\n* Static Type Checker: `MyPy \u003chttps://mypy.readthedocs.io/\u003e`_\n* Style Enforcement/Linter: `Flake8 \u003chttps://flake8.pycqa.org/\u003e`_\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprofusion%2Fpf-video-transcribe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprofusion%2Fpf-video-transcribe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprofusion%2Fpf-video-transcribe/lists"}