{"id":13803519,"url":"https://github.com/fengalin/media-toc","last_synced_at":"2025-06-29T23:37:10.143Z","repository":{"id":22154480,"uuid":"95443101","full_name":"fengalin/media-toc","owner":"fengalin","description":"Build a table of contents from a media file or split a media file into chapters","archived":false,"fork":false,"pushed_at":"2023-04-04T07:57:04.000Z","size":14249,"stargazers_count":73,"open_issues_count":23,"forks_count":3,"subscribers_count":7,"default_branch":"main","last_synced_at":"2024-11-18T19:42:43.912Z","etag":null,"topics":["audio-video","chapter","gstreamer","rust","table-of-contents"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fengalin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2017-06-26T12:15:28.000Z","updated_at":"2024-08-03T19:01:38.000Z","dependencies_parsed_at":"2024-08-04T01:12:37.658Z","dependency_job_id":null,"html_url":"https://github.com/fengalin/media-toc","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fengalin%2Fmedia-toc","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fengalin%2Fmedia-toc/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fengalin%2Fmedia-toc/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fengalin%2Fmedia-toc/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fengalin","download_url":"https://codeload.github.com/fengalin/media-toc/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":231727106,"owners_count":18417391,"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":["audio-video","chapter","gstreamer","rust","table-of-contents"],"created_at":"2024-08-04T01:00:34.382Z","updated_at":"2024-12-29T10:36:08.535Z","avatar_url":"https://github.com/fengalin.png","language":"Rust","readme":"# media-toc ![CI](https://github.com/fengalin/media-toc/workflows/CI/badge.svg) [![dependency status](https://deps.rs/repo/github/fengalin/media-toc/status.svg)](https://deps.rs/repo/github/fengalin/media-toc)\n\n![media-toc logo](res/icons/banner/org.fengalin.media-toc.png \"media-toc logo\")\n\n**media-toc** is an application to build a table of contents from a media file or to split a media\nfile into chapters.\n\nYou might also be interested in [media-toc-player](https://github.com/fengalin/media-toc-player):\na media player with a table of contents.\n\n## Table of contents\n\n- [Screenshots](#ui)\n- [Features](#features)\n- [Accelerators](#accelerators)\n- [how-to](#how-to)\n  * [Create the table of contents](#how-to-create-the-toc)\n  * [Save the table of contents](#how-to-save-the-toc)\n  * [Export the resulting media with its table of contents to a Matroska container](#export-to-mkv)\n  * [Split the audio stream into one file per chapter](#split-to-audio)\n  * [Use `mkvmerge` to add the toc to an existing Matrsoka media](#use-mkvmerge)\n- [Technologies](#technologies)\n- [Build environment](#build-env)\n- [Get the sources](#get-sources)\n- [Build and run](#build-run)\n- [Troubleshooting](#troubleshooting)\n\n## \u003ca name='ui'\u003e\u003c/a\u003eScreenshots\n\n### media-toc playing a video\n\n![media-toc UI Video](assets/screenshots/media-toc_video.png \"media-toc UI Video\")\n\n### media-toc playing an audio file, French localization\n\n![media-toc UI Audio](assets/screenshots/media-toc_audio.png \"media-toc UI Audio\")\n\n## \u003ca name='features'\u003e\u003c/a\u003eFeatures\n\n- Play/Pause an audio/video media\n- Select the streams to play.\n- Draw the audio waveform and chapters boundaries.\n- Seek in the media by left clicking on the waveform, on the timeline or in the chapters list.\n- Play from a position until the end of current time frame by right clicking on the waveform\n  at the starting position in paused mode.\n- Zoom in/out the waveform on the time axis.\n- Add/remove a chapter.\n- Drag chapters boundaries in order to adjust their position.\n- Play current chapter in a loop.\n- Export the table of contents to:\n\t* A Matroska container. Currently, this is only possible if the input streams are compatible\n\twith Matroska containers. I'll add an UI to allow converting streams later. This requires\n\t[`gst-plugins-good` 1.14](https://gstreamer.freedesktop.org/releases/1.14/) or above.\n\t* [mkvmerge simple chapter format](https://mkvtoolnix.download/doc/mkvmerge.html#mkvmerge.chapters).\n\t* [Cue Sheet](http://wiki.hydrogenaud.io/index.php?title=Cue_sheet).\n- Split currently selected audio stream into `flac`, `wave`, `opus`, `vorbis` or `mp3` files:\n  one file per chapter.\n- Import the table of contents from:\n\t* A Matroska container.\n\t* [mkvmerge simple chapter format](https://mkvtoolnix.download/doc/mkvmerge.html#mkvmerge.chapters).\n\n## \u003ca name='accelerators'\u003e\u003c/a\u003eAccelerators\n\nThe following functions are bound to one or multiple key accelerators:\n\n| Function                                                   | keys                                |\n| ---------------------------------------------------------- | :---------------------------------: |\n| Open media dialog                                          | \u003ckbd\u003eControl\u003c/kbd\u003e + \u003ckbd\u003eO\u003c/kbd\u003e   |\n| Quit the application                                       | \u003ckbd\u003eControl\u003c/kbd\u003e + \u003ckbd\u003eQ\u003c/kbd\u003e   |\n| Play/Pause (and open media dialog when no media is loaded) | \u003ckbd\u003eSpace\u003c/kbd\u003e or \u003ckbd\u003ePlay\u003c/kbd\u003e |\n| Step forward                                               | \u003ckbd\u003eRight\u003c/kbd\u003e                    |\n| Step back                                                  | \u003ckbd\u003eLeft\u003c/kbd\u003e                     |\n| Go to next chapter                                         | \u003ckbd\u003eDown\u003c/kbd\u003e or \u003ckbd\u003eNext\u003c/kbd\u003e  |\n| Go to the beginning of current chapter or previous chapter | \u003ckbd\u003eUp\u003c/kbd\u003e or \u003ckbd\u003ePrev\u003c/kbd\u003e    |\n| Zoom the waveform in                                       | \u003ckbd\u003eZ\u003c/kbd\u003e                        |\n| Zoom the waveform out                                      | \u003ckbd\u003eShitf\u003c/kbd\u003e + \u003ckbd\u003eZ\u003c/kbd\u003e     |\n| Close the info bar                                         | \u003ckbd\u003eEscape\u003c/kbd\u003e                   |\n| Add a chapter at current position                          | \u003ckbd\u003e+\u003c/kbd\u003e                        |\n| Remove the chapter at current position                     | \u003ckbd\u003e-\u003c/kbd\u003e                        |\n| Toggle show/hide chapters list                             | \u003ckbd\u003eL\u003c/kbd\u003e                        |\n| Toggle repeat current chapter                              | \u003ckbd\u003eR\u003c/kbd\u003e                        |\n| Show the Display perspective                               | \u003ckbd\u003eF5\u003c/kbd\u003e                       |\n| Show the Streams perspective                               | \u003ckbd\u003eF6\u003c/kbd\u003e                       |\n| Show the Export perspective                                | \u003ckbd\u003eF7\u003c/kbd\u003e                       |\n| Show the Split perspective                                 | \u003ckbd\u003eF8\u003c/kbd\u003e                       |\n| Open the about dialog                                      | \u003ckbd\u003eControl\u003c/kbd\u003e + \u003ckbd\u003eA\u003c/kbd\u003e   |\n\n# \u003ca name='how-to'\u003e\u003c/a\u003eHow-to\n\n## \u003ca name='how-to-create-the-toc'\u003e\u003c/a\u003eCreate the table of contents\n\n1. Click on the folder icon or the play icon to open the file selection dialog.\n2. Select the mkv media for which you want to add a table of contents.\n3. If you want to add a chapter starting at the begining of the file, you can click on the `+` icon\nunder the tree view at the bottom right of the window. The end of the chapter will match the end\nof the media. This will change automatically if you add new chapters.\n4. Click in the newly added chapter title column and fill the title for this chapter.\n5. Play the stream until the next chapter's starting position. You can use the timeline to seek\nin the media.\n6. In order to precisely define the start of the new chapter, pause the media by clicking on the\nplay/pause button, then use the `+` button next to the waveform to zoom in. You can then seek around\ncurrent sample by clicking on the waveform. You can also play the media in current time frame by\nright clicking at the starting position. Use the zoom, left click and right click until you reach\nthe position for the chapter to add.\n7. When the cursor (the vertical yellow bar) matches the start of the chapter to add, click on the\n`+` icon under the tree view at the bottom right of the window.\n8. If you want to modify chapters boundary, click and drag the boundary to modify to the desired\nposition. Note: this operation is only available in paused mode.\n9. Click in the newly added chapter title column and fill a title for this chapter.\n10. Go back to step 5 if you wish to add another chapter.\n\n## \u003ca name='how-to-save-the-toc'\u003e\u003c/a\u003eSave the table of contents\n\nYou can export a table of contents to the `mkvmerge simple chapter format` which is a text file.\nThis file will be stored in the same folder as the original media and will be automatically loaded\nnext time you open this media.\n\n1. Define the chapters as explained in [this how-to](#how-to-create-the-toc).\n2. Switch to the Export perspective using the selector on the left side of the header bar.\n3. Select `mkvmerge text format`.\n4. Click on `Export`. When the export is complete, a new file with the same name as your media and\nwith a `txt` extension will be created in the media's folder.\n\n## \u003ca name='export-to-mkv'\u003e\u003c/a\u003eExport the resulting media with its table of contents to a Matroska container\n\nCurrently, this is only possible if the input streams are compatible with Matroska containers.\n\nWarning: this also requires [`gst-plugins-good` 1.14](https://gstreamer.freedesktop.org/releases/1.14/)\nor above.\n\n1. Open a media with a table of contents, define the chapters as explained in [this how-to](#how-to-create-the-toc)\nor open a media for which you already defined a table of contents (see [this how-to](#how-to-save-the-toc)).\n2. Switch to the Streams perspective using the selector on the left side of the header bar.\n3. Tick the streams to export (all streams are ticked by default).\n4. Switch to the Export perspective using the selector on the left side of the header bar.\n5. Select `Matroska Container`.\n6. Click on `Export`. When the export is complete, a new file with the same name as your media and\nending with `.toc.mkv` will be created in the media's folder.\n\n## \u003ca name='split-to-audio'\u003e\u003c/a\u003eSplit the audio stream into one file per chapter\n\n1. Open a media with a table of contents, define the chapters as explained in [this how-to](#how-to-create-the-toc)\nor open a media for which you already defined a table of contents (see [this how-to](#how-to-save-the-toc)).\n2. Switch to the Streams perspective using the selector on the left side of the header bar.\n3. Select the audio stream to split.\n4. Switch to the Split perspective using the selector on the left side of the header bar.\n5. Select to desired output format: `flac`, `wave`, `opus`, `vorbis` or `mp3`.\n6. Click on `Split`. When the split is complete, audio files will be created in the media's folder.\nThe files are named after the artist, media title, chapter number and chapter title.\n\n## \u003ca name='use-mkvmerge'\u003e\u003c/a\u003eUse `mkvmerge` to add the toc to an existing Matrsoka media\n\nExporting the table of contents to a Matroska container requires [`gst-plugins-good` 1.14](https://gstreamer.freedesktop.org/releases/1.14/)\nor above. If you use an ealier version, follow these instructions:\n\n1. Install `mkvtoolnix` using your package manager.\n2. Export your table of contents to the `mkvmerge simple chapter format` (see [this how-to](#how-to-save-the-toc)).\n3. Open a terminal and `cd` to the directory where your Matroska file is located.\n4. Issue the following command (where _media_ is the name of your mkv file without the extension):\n\n    ```\n    mkvmerge --chapters _media_.txt -o output_file.mkv _media_.mkv\n    ```\n\nThe file `output_file.mkv` will now contain the media with the chapters you defined.\n\n# \u003ca name='technologies'\u003e\u003c/a\u003eTechnologies\n\n**media-toc** is developed in Rust and uses the following technologies:\n- **GTK-3** ([official documentation](https://developer.gnome.org/gtk3/stable/),\n[Rust binding](http://gtk-rs.org/docs/gtk/)) and [Glade](https://glade.gnome.org/).\n- **Cairo** ([official documentation](https://www.cairographics.org/documentation/),\n[Rust binding](http://gtk-rs.org/docs/cairo/index.html)).\n- **GStreamer** ([official documentation](https://gstreamer.freedesktop.org/documentation/),\n[Rust binding](https://sdroege.github.io/rustdoc/gstreamer/gstreamer/)).\n\n# \u003ca name='build-env'\u003e\u003c/a\u003eBuild environment\n\n## Toolchain\n\n```\n$ curl https://sh.rustup.rs -sSf | sh\n```\n\nSelect the `stable` toolchain. See the full documentation\n[here](https://github.com/rust-lang-nursery/rustup.rs#installation).\n\nIt is convenient to have Rust's tools in the path. On linux, you might want to add this\nin your `.bashrc`:\n\n```\nexport PATH=$PATH:~/.cargo/bin\n```\n\n## Dependencies\n\nRust dependencies are handled by [Cargo](http://doc.crates.io/). You will also\nneed the following packages installed on your OS:\n\n### Fedora\n\n```\nsudo dnf install gcc gtk3-devel glib2-devel gstreamer1-devel \\\n\tgstreamer1-plugins-base-devel gstreamer1-plugins-{good,bad-free,ugly-free} \\\n\tgstreamer1-libav\n```\n\n### Debian \u0026 Ubuntu\n\n```\nsudo apt-get install gcc libgtk-3-dev libgstreamer1.0-dev \\\n\tlibgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-{good,bad,ugly} \\\n\tgstreamer1.0-gtk3 gstreamer1.0-libav\n```\n\n### macOS\n\nNote: the mac I used to test these instructions is pretty old. It's stucked\non an old version of the OS and doesn't get precompiled packages from __homebrew__.\nPlease [fill an issue](https://github.com/fengalin/media-toc/issues) if you run\ninto any problem.\n\n- Install [homebrew](https://brew.sh/).\n- Install `git` from homebrew:\n\n  ```\n  brew install git\n  ```\n\n- Install [Rust toolchain manager](https://rustup.rs/) and select the `stable`\ntoolchain.\n- Add Rust tools in the `PATH`:\n\n  ```\n  echo \"export PATH=\\$PATH:$HOME/.cargo/bin\" \u003e\u003e $HOME/.bashrc\n  source $HOME/.bashrc\n  ```\n\n- Install dependencies:\n\n  ```\n  brew install gtk+3 gstreamer adwaita-icon-theme\n  brew install --with-libvorbis --with-opus --with-theora gst-plugins-base\n  brew install --with-flac --with-gtk+3 --with-libpng --with-taglib gst-plugins-good\n  brew install --with-srt gst-plugins-bad\n  brew install --with-libmpeg2 --with-x264 gst-plugins-ugly\n  ```\n\nUse the following command to build and generate locales:\n\n```\nPATH=\"/usr/local/opt/gettext/bin:$PATH\" cargo build --release --features=gettext\n```\n\n### Windows\n\nPlease note that I don't have any Windows box at hand ATM. These instructions\nmight be out of date. If you figure out a proper set of dependencies, please\nsubmit a PR.\n\n- MSYS2: follow [this guide](http://www.msys2.org/).\n- Install the development toolchain, GTK and GStreamer\u003cbr\u003e\nNote: for a 32bits system, use `mingw-w64-i686-...`\n\n  ```\n  pacman --noconfirm -S mingw-w64-x86_64-pkg-config mingw-w64-x86_64-gtk3 mingw-w64-x86_64-gstreamer\n  pacman --noconfirm -S mingw-w64-x86_64-gst-plugins-{base,good,bad,ugly} mingw-w64-x86_64-gst-libav\n  ```\n\n  If you want the application to be localized (currently only in French or Spanish),\n  also install:\n\n  ```\n  pacman --noconfirm -S gettext-devel\n  ```\n\n- Launch the [rustup installer](https://www.rustup.rs/).\nWhen asked for the default host triple, select `x86_64-pc-windows-gnu` (or\n`i686-pc-windows-gnu` for a 32bits system), then select `stable`.\n- From a MSYS2 MinGW 32 or 64 shell\n  - add cargo to the `PATH`:\n\n      ```\n      echo 'PATH=$PATH:/c/Users/'$USER'/.cargo/bin' \u003e\u003e /home/$USER/.bashrc\n      ```\n\n  - Restart the MSYS2 MinGW 32 or 64 shell before using `cargo`.\n\n# \u003ca name='get-sources'\u003e\u003c/a\u003eGet the sources\n\nThis will retrieve the last release.\n\n  ```\n  git clone --branch v0.7.0 https://github.com/fengalin/media-toc\n  cd media-toc\n  ```\n\n# \u003ca name='build-run'\u003e\u003c/a\u003eBuild and run\n\nUse Cargo (from the root of the project):\n\n```\ncargo run --release\n```\n\nIf you want the application to be localized (currently only in French or Spanish),\ncompile with `gettext` support:\n\n```\ncargo run --release --features=gettext\n```\n\nOn XDG compliant systems, you can install the application executable and related\nfiles (icons, translations and desktop file) for current user by executing the\nfollowing command (from the root of the project):\n```\nbash target/install\n```\n\nYou can uninstall with:\n```\nbash target/uninstall\n```\n\n# \u003ca name='troubleshooting'\u003e\u003c/a\u003eTroubleshooting\n\n## Can't play a video file or the UI doesn't refresh properly\n\nThis might be caused by the hardware acceleration which is enabled by default.\nIn some cases, the application will detect the issue and disable it automatically\n(a restart is required). But in other cases, you may have to disable it by hand.\nFirst check that hardware acceleration is indeed the issue:\n```\ncargo run -- --disable-gl\n```\n\nIf it solves the problem, you can permanently disable hardware acceleration by editing\nthe configuration file. The configuration location depends on the operating system:\n\n\n| OS          | Configuration location                                                       |\n| ----------- | ---------------------------------------------------------------------------- |\n| Linux based | ~/.config/media-toc/config.ron                                               |\n| macOS       | /Users/_user_/Library/Preferences/org.fengalin.media-toc/config.ron          |\n| Windows     | C:\\\\Users\\\\_user_\\\\AppData\\\\Roaming\\\\fengalin\\\\media-toc\\\\config\\\\config.ron |\n\n\nOpen the configuration file and replace the following line:\n\n```\n        is_gl_disabled: false,\n```\n\nwith:\n\n```\n        is_gl_disabled: true,\n```\n\n## Discarding translations\n\n*media-toc* is currently available in English, French and Spanish. The user\nlocale should be automatically detected when the application is compiled with\nthe `gettext` feature. If you want to use the English version or if you want\nto submit logs, you can discard the translations using the following command:\n\n```\nLC_MESSAGES=C cargo run --release\n```\n","funding_links":[],"categories":["Video"],"sub_categories":["Video Tools"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffengalin%2Fmedia-toc","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffengalin%2Fmedia-toc","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffengalin%2Fmedia-toc/lists"}