{"id":17526943,"url":"https://github.com/sandflow/ttconv","last_synced_at":"2026-04-12T06:04:31.207Z","repository":{"id":41865787,"uuid":"294991067","full_name":"sandflow/ttconv","owner":"sandflow","description":"Subtitle conversion library and CLI tool. Converts between STL, SRT, TTML, SCC, TTML and WebVTT files.","archived":false,"fork":false,"pushed_at":"2026-03-30T23:48:49.000Z","size":979,"stargazers_count":230,"open_issues_count":30,"forks_count":33,"subscribers_count":18,"default_branch":"master","last_synced_at":"2026-04-03T05:36:29.150Z","etag":null,"topics":["608","708","caption","converter","ebu-stl","format","imsc","scc","smpte-tt","srt","stl","ttml","webvtt"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sandflow.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-09-12T17:17:46.000Z","updated_at":"2026-03-30T23:46:32.000Z","dependencies_parsed_at":"2026-01-02T16:00:12.274Z","dependency_job_id":null,"html_url":"https://github.com/sandflow/ttconv","commit_stats":{"total_commits":148,"total_committers":7,"mean_commits":"21.142857142857142","dds":0.5,"last_synced_commit":"3c4d4798fb81dd509ca7fabc4a4438dc19e611cf"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"purl":"pkg:github/sandflow/ttconv","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sandflow%2Fttconv","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sandflow%2Fttconv/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sandflow%2Fttconv/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sandflow%2Fttconv/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sandflow","download_url":"https://codeload.github.com/sandflow/ttconv/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sandflow%2Fttconv/sbom","scorecard":{"id":799047,"data":{"date":"2025-08-11","repo":{"name":"github.com/sandflow/ttconv","commit":"69a59ee3e3c6645d30adeb537ce95eb2f751b0af"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.1,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":3,"reason":"Found 11/30 approved changesets -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/main.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.txt:0","Info: FSF or OSI recognized license: BSD 2-Clause \"Simplified\" License: LICENSE.txt:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/sandflow/ttconv/main.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/main.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/sandflow/ttconv/main.yml/master?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:1: pin your Docker image by updating python:3.7-buster to python:3.7-buster@sha256:2539f956bcccbac5e4a48ebdafbbbfbd26b4ab56e65b96076ae9cd1188b119b3","Warn: pipCommand not pinned by hash: .github/workflows/main.yml:17","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 containerImage dependencies pinned","Info:   0 out of   1 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 25 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-23T09:53:49.071Z","repository_id":41865787,"created_at":"2025-08-23T09:53:49.071Z","updated_at":"2025-08-23T09:53:49.071Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31705574,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-12T05:11:36.334Z","status":"ssl_error","status_checked_at":"2026-04-12T05:11:27.332Z","response_time":58,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["608","708","caption","converter","ebu-stl","format","imsc","scc","smpte-tt","srt","stl","ttml","webvtt"],"created_at":"2024-10-20T15:02:38.878Z","updated_at":"2026-04-12T06:04:31.159Z","avatar_url":"https://github.com/sandflow.png","language":"Python","readme":"# ttconv (Timed Text Conversion)\n\n      $$\\     $$\\                                             \n      $$ |    $$ |                                            \n    $$$$$$\\ $$$$$$\\    $$$$$$$\\  $$$$$$\\  $$$$$$$\\ $$\\    $$\\ \n    \\_$$  _|\\_$$  _|  $$  _____|$$  __$$\\ $$  __$$\\\\$$\\  $$  |\n      $$ |    $$ |    $$ /      $$ /  $$ |$$ |  $$ |\\$$\\$$  / \n      $$ |$$\\ $$ |$$\\ $$ |      $$ |  $$ |$$ |  $$ | \\$$$  /  \n      \\$$$$  |\\$$$$  |\\$$$$$$$\\ \\$$$$$$  |$$ |  $$ |  \\$  /   \n       \\____/  \\____/  \\_______| \\______/ \\__|  \\__|   \\_/    \n\n## Introduction\n\n_ttconv_ is a library and command line application written in pure Python for\nconverting between timed text formats used in the presentations of captions,\nsubtitles, karaoke, etc.\n\n    TTML / IMSC ---                                       ---- IMSC / TTML\n                    \\                                   /\n    SCC / CTA 608 ------- 0 or more document filters --------- WebVTT\n                    /        [ Canonical Model ]        \\\n    EBU STL -------                                       ---- SRT\n                  /                                        \\\n    SRT ---------                                           -- SCC / CTA 608\n                /\n    WebVTT ----\n\n_ttconv_ works by mapping the input document, whatever its format, into an\ninternal canonical model, which is then optionally transformed by document\nfilters, and finally mapped to the format of the output document is derived. The\ncanonical model closely follows the [TTML 2](https://www.w3.org/TR/ttml2) data\nmodel, as constrained by the [IMSC 1.3 Text\nProfile](https://www.w3.org/TR/ttml-imsc1.3/#profiles) specification.\n\n## Online demo\n\n[https://ttconv.sandflow.com/](https://ttconv.sandflow.com/)\n\n## Format support\n\n_ttconv_ currently supports the following input and output formats. Additional input and output formats are planned, and\nsuggestions/contributions are welcome.\n\n### Input Formats\n\n* [CTA 608/.scc](https://en.wikipedia.org/wiki/EIA-608)\n* [IMSC 1.3 Text Profile](https://www.w3.org/TR/ttml-imsc1.3/#profiles)\n* [EBU STL](https://tech.ebu.ch/docs/tech/tech3264.pdf)\n* [SubRip/.srt](https://en.wikipedia.org/wiki/SubRip)\n* [WebVTT](https://www.w3.org/TR/webvtt1/)\n\n### Output Formats\n\n* [SubRip/.srt](https://en.wikipedia.org/wiki/SubRip)\n* [IMSC 1.3 Text Profile](https://www.w3.org/TR/ttml-imsc1.3/#profiles)\n* [WebVTT](https://www.w3.org/TR/webvtt1/)\n* [CTA 608/.scc](https://en.wikipedia.org/wiki/EIA-608)\n\n## Quick start\n\nTo install the latest version of `ttconv`, including pre-releases:\n\n```sh\npip install --pre ttconv\n\ntt convert -i \u003cinput .scc file\u003e -o \u003coutput .ttml file\u003e\n```\n\n## Documentation\n\n### Command line\n\n`tt convert [-h] -i INPUT -o OUTPUT [--itype ITYPE] [--otype OTYPE] [--config CONFIG] [--config_file CONFIG_FILE]`\n\n* `--itype`: `TTML` | `SCC` | `STL` | `SRT` (extrapolated from the filename, if omitted)\n* `--otype`: `TTML` | `SCC` | `SRT` | `VTT` (extrapolated from the filename, if omitted)\n* `--filter`: specifies by name a filter to be applied to the content\n* `--config` and `--config_file`: JSON dictionary where each property specifies\n  (optional) configuration parameters for readers, writers and filters.\n\nExample:\n\n`tt convert -i \u003c.scc file\u003e -o \u003c.ttml file\u003e --itype SCC --otype TTML --filter lcd --config '{\"general\": {\"progress_bar\":false, \"log_level\":\"WARN\"}, \"lcd\": {\"bg_color\": \"transparent\", \"color\": \"#FF0000\"}}'`\n\n### General configuration (`\"general\"`)\n\n#### progress_bar\n\n`\"progress_bar\": true | false`\n\nA progress bar is displayed if `progress_bar` is `true` and `log_level` is `\"INFO\"`.\n\nDefault: `true`\n\n#### log_level\n\n`\"log_level\": \"DEBUG\" | \"INFO\" | \"WARN\" | \"ERROR\"`\n\nLogging verbosity\n\nDefault: `\"INFO\"`\n\n#### document_lang\n\n`\"document_lang\": \u003cRFC 5646 language tag\u003e`\n\nOverrides the top-level language of the input document.\n\nExample: `\"document_lang\": \"es-419\"`\n\nDefault: `None`\n\n### IMSC Writer configuration (`\"imsc_writer\"`)\n\n#### time_format\n\n`\"time_format\": \"frames\" | \"clock_time\" | \"clock_time_with_frames\"`\n\nSpecifies whether the TTML time expressions are in frames (`f`), `HH:MM:SS.mmm` or `HH:MM:SS:FF`\n\nDefault: `\"frames\"` if `\"fps\"` is specified, `\"clock_time\"` otherwise\n\n#### fps\n\n`\"fps\": \"\u003cnum\u003e/\u003cdenom\u003e\"`\n\nSpecifies the `ttp:frameRate` and `ttp:frameRateMultiplier` of the output document.\n\nRequired when `time_format` is `frames` or `clock_time_with_frames`. No effect otherwise.\n\nExample:\n\n`--config '{\"general\": {\"progress_bar\":false, \"log_level\":\"WARN\"}, \"imsc_writer\": {\"time_format\":\"clock_time_with_frames\", \"fps\": \"25/1\"}}'`\n\n#### profile_signaling\n\n`\"profile_signaling\": \"none\" | \"content_profiles\"`\n\nSpecifies whether and how the output TTML document signals conformance to profile:\n\n* `\"none\"`: no profile conformance is signalled\n* `\"content_profiles\"`: if available, content profile conformance is signaled using the `ttp:contentProfiles` attribute\n\nDefault: `\"none\"`\n\nExample:\n\n`--config '{ \"imsc_writer\" : { \"profile_signaling\" : \"content_profiles\" } }'`\n\n_NOTE_: Profile conformance signalling is neither required by IMSC not TTML, and is prohibited by some applications, e.g., EBU-TT-D, and some versions of IMSC. Moreover, profile conformance cannot always be determined. As a result, profile conformance should be signaled only when required by the application.\n\n### STL Reader configuration (`\"stl_reader\"`)\n\n#### disable_fill_line_gap\n\n`\"disable_fill_line_gap\" : true | false`\n\n`true` means that the STL reader does not fill gaps between lines\n\nDefault: `false`\n\n#### disable_line_padding\n\n`\"disable_line_padding\" : true | false`\n\n`true` means that the STL reader does not add padding at the begining/end of lines\n\nDefault: `false`\n\n#### program_start_tc\n\n`\"program_start_tc\" : \"TCP\" | \"HH:MM:SS:FF\"`\n\nSpecifies a starting offset, either the TCP field of the GSI block or a user-specified timecode\n\nDefault: `\"00:00:00:00\"`\n\n#### font_stack\n\n`\"font_stack\" : [\u003cfont-families\u003e](https://www.w3.org/TR/ttml2/#style-value-font-families)`\n\nOverrides the font stack\n\nDefault: `\"Verdana, Arial, Tiresias, sansSerif\"`\n\n#### max_row_count\n\n`\"max_row_count\" : \"MNR\" | integer`\n\nSpecifies a maximum number of rows for open subtitles, either the MNR field of the GSI block or a user-specified value\n\nDefault: `23`\n\n### SRT Writer configuration (`\"srt_writer\"`)\n\n#### text_formatting\n\n`\"text_formatting\" : true | false`\n\n`false` means that the SRT writer does not output any text formatting tags\n\nDefault: `true`\n\n### SRT Reader configuration (`\"srt_reader\"`)\n\n#### extended_tags\n\n`\"extended_tag\" : true | false`\n\nIf `true`, the following extended formatting tags are supported: `{bold}`,\n`\u003cbold\u003e`, `{b}`, `{italic}`, `\u003citalic\u003e`, `{i}`, `{underline}`, `\u003cunderline\u003e` and\n`{u}`.\n\nDefault: `false`\n\n#### alignment_tags\n\n`\"alignment_tags\" : true | false`\n\nIf `true`, ASS/SSA-style alignment tags (`{\\anN}`) are supported, where N is a\nnumber from 1-9 corresponding to positions on a numpad:\n\n* 1-3: bottom (left, center, right)\n* 4-6: middle (left, center, right)\n* 7-9: top (left, center, right)\n\nDefault: `false`\n\n### VTT Writer configuration (`\"vtt_writer\"`)\n\n#### line_position\n\n`\"line_position\" : true | false`\n\n`true` means that the VTT writer outputs line and line alignment cue settings\n\nDefault: `false`\n\n#### text_align\n\n`\"text_align\" : true | false`\n\n`true` means that the VTT writer outputs text alignment cue settings\n\nDefault: `false`\n\n#### cue_id\n\n`\"cue_id\" : true | false`\n\n`true` means that the VTT writer outputs cue identifiers\n\nDefault: `true`\n\n### SCC Reader configuration\n\n#### text_align\n\n`\"text_align\" : \"auto\" | \"left\" | \"center\" | \"right\"`\n\nSpecifies the text alignment. `\"auto\"` means the reader will use heuristics to determine\ntext alignment.\n\nDefault: `\"auto\"`\n\n### SCC Writer configuration\n\n#### allow_reflow\n\n`\"allow_reflow\" :  true | false`\n\nIf `true`, the writer reflows text to fit within the 32 columns.\n\nDefault: `true`\n\n#### force_popon\n\n`\"force_popon\" :  true | false`\n\nIf `true`, the writer does not detect roll-up captions and always emits pop-on captions.\n\nDefault: `false`\n\n#### rollup_lines\n\n`\"rollup_lines\" :  2 | 3 | 4`\n\nSpecifies the number of lines the writer should use in the roll-up region.\n\nDefault: `4`\n\n#### frame_rate\n\n`\"frame_rate\" : \"30NDF\" | \"29.97NDF\" | \"29.97DF\"`\n\nIf `frame_rate` is:\n* `\"30NDF\"`, the output SCC file uses 30 fps non drop frame (NDF) timecode.\n* `\"29.97NDF\"`, the output SCC file uses 29.97 fps non drop frame (NDF) timecode.\n* `\"29.97DF\"`, the output SCC file uses 29.97 fps drop frame (DF) timecode.\n\nDefault: `\"2997DF\"`\n\n#### start_tc\n\n`\"start_tc\" : null | \"HH:MM:SS:FF\" | \"HH;MM;SS;FF\"`\n\nIf not `null`, specifies the starting timecode for the SCC file. The timecode\nmust be consistent with the value of the `frame_rate` parameter.\n\nDefault: `null`\n\n### LCD filter configuration (`\"lcd\"`)\n\n#### Description\n\nThe LCD filter merges regions and removes all text formatting with the exception\nof color and text alignment.\n\n#### safe_area\n\n`\"safe_area\" : \u003cinteger between 0 and 30\u003e`\n\nSpecifies the safe area (as a percentage of the height and width of the root container)\n\nDefault: `10`\n\n#### color\n\n`\"color\" : \u003cTTML color\u003e | null`\n\nIf not `null`, overrides text color. The syntax of `TTML color` is\nspecified at \u003chttps://www.w3.org/TR/ttml2/#style-value-color\u003e.\n\nDefault: `null`\n\nExamples: `\"#FFFFFF\"` (white), `\"white\"`\n\n#### bg_color\n\n`\"bg_color\" : \u003cTTML color\u003e`\n\nIf not `null`, overrides the background color. The syntax of `TTML color` is\nspecified at \u003chttps://www.w3.org/TR/ttml2/#style-value-color\u003e.\n\nDefault: `null`\n\nExamples: `\"#FF0000\"` (red), `\"transparent\"`, `\"black\"`\n\n#### preserve_text_align\n\n`\"preserve_text_align\" : true | false`\n\nIf `true`, text alignment is preserved, otherwise text is centered.\n\nDefault: `false`\n\n### IMSC 1.1 Text Profile filter configuration (`\"imsc11text\"`)\n\n#### Description\n\nThe IMSC 1.1 Text Profile filter checks the document against major deviations\nfrom the [IMSC 1.1 Text Profile](https://www.w3.org/TR/ttml-imsc1.1/#text-profile).\nAny deviation results in the filter raising an exception. The absence of deviation\nresults in the [IMSC 1.1 Text Profile designator](https://www.w3.org/TR/ttml-imsc1.1/#text-profile-designator)\nbeing added to the `ttp:contentProfiles` parameter.\n\nThis filter has no configuration parameters.\n\n_NOTE_: This filter is not currently intended as substitute for a full IMSC 1.1 validator.\n\n#### Example\n\n    tt convert -i input.vtt -o output.ttml --filter imsc11text\n\n## Library\n\nThe overall architecture of the library is as follows:\n\n* Reader modules validate and convert input files into instances of the canonical model (see `ttconv.imsc.reader.to_model()` for\n  example);\n* Filter modules transform instances of the canonical data model, e.g. all text styling and positioning might be removed from an\n  instance of the canonical model to match the limited capabilities of downstream devices; and\n* Writer modules convert instances of the canonical data model into output files.\n\nProcessing shared across multiple reader and writer modules is factored out in common modules whenever possible. For example,\nseveral output formats require an instance of the canonical data model to be transformed into a sequence of discrete temporal\nsnapshots – a process called ISD generation.\n\nThe library uses the Python `logging` module to report non-fatal events.\n\nUnit tests illustrate the use of the library, e.g. `ReaderWriterTest.test_imsc_1_test_suite` at\n`src/test/python/test_imsc_writer.py`.\n\nDetailed documentation including reference documents is under [`doc`](./doc).\n\n## Dependencies\n\n### Runtime\n\n* [python \u003e= 3.7](https://python.org)\n\n### Development\n\nThe project uses [pipenv](https://pypi.org/project/pipenv/) to manage dependencies.\n\n* [pylint](https://pypi.org/project/pylint/)\n* [coverage](https://pypi.org/project/coverage/)\n\n## Development\n\n### Setup\n\n#### Local\n\n* run `pipenv install --dev`\n* set the `PYTHONPATH` environment variable to `src/main/python`, e.g. `export PYTHONPATH=src/main/python`\n* `pipenv run` can then be used\n\n#### Docker\n\n```sh\ndocker build --rm -f Dockerfile -t ttconv:latest .\ndocker run -it --rm ttconv:latest bash\n```\n\n### Example\n\nFrom the root directory of the project:\n\n```sh\nmkdir build\npipenv install --dev\nexport PYTHONPATH=src/main/python\npython src/main/python/ttconv/tt.py convert -i src/test/resources/scc/mix-rows-roll-up.scc -o build/mix-rows-roll-up.ttml\n```\n\n### Code coverage\n\nUnit test code coverage is provided by the script at `scripts/coverage.sh`\n\n### Continuous integration\n\n#### Overview\n\nAutomated testing is provided by the script at `scripts/ci.sh`\n\n#### Local\n\nRun `PYTHONPATH=src/main/python ./scripts/ci.sh`\n\n#### GitHub actions\n\nSee `.github/workflows/main.yml`\n\n#### Docker\n\nRun `docker run -it --rm  ttconv:latest /bin/sh scripts/ci.sh`\n","funding_links":[],"categories":["Python","Video Editing \u0026 Processing Tools","Subtitling","Open-Source Libraries"],"sub_categories":["Subtitle \u0026 Caption Tools","Subtitle Processing"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsandflow%2Fttconv","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsandflow%2Fttconv","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsandflow%2Fttconv/lists"}