otr-utils 0.5.1

Utilities for decoding and cutting video files that were downloaded from Online TV Recorder <https://onlinetvrecorder.com/>
Documentation
// SPDX-FileCopyrightText: 2024 Michael Picht <mipi@fsfe.org>
//
// SPDX-License-Identifier: GPL-3.0-or-later

//! # otr-utils
//!
//! otr-utils provides tools to decode and cut video files from [Online TV Recorder](https://www.onlinetvrecorder.com/)
//! (OTR).
//!
//! ## Decoding
//!
//! Decoding of OTRKEY files (i.e., encoded video files downloaded from OTR) is
//! supported. The decoding functionality is based on the work of eddy14, who
//! reverse-engineered the OTRKEY file format, see [his blog post](https://pyropeter.eu/41yd.de/blog/2010/04/18/otrkey-breaker/)
//! [German, mirrored by [PyroPeter](https://github.com/pyropeter)].
//!
//! Example:
//! The path of the video to be decoded (i.e., the OTRKEY file), the path of the
//! decoded video, as well as user and password for OnlineTVRecorder are
//! submitted as command line parameters.
//!
//! ```edition2021
//!     let args: Vec<String> = std::env::args().collect();
//!
//!     let in_video = &args[1];
//!     let out_video = &args[2];
//!     let user = &args[3];
//!     let password = &args[4];
//!
//!     if let Err(err) = otr_utils::decoding::decode(in_video, out_video, user, password) {
//!         eprintln!("{:?}", err);
//!     }
//! ```
//!
//! ## Cutting
//!
//! Cutting of decoded videos is done by using [FFmpeg](https://ffmpeg.org/) together
//! with [FFMS2](https://github.com/FFMS/ffms2). It is done **accurate to frames**.
//! I.e., even if a boundary of a cut interval is not at a key frame, cutting is done
//! exactly at that boundary. To achieve this, parts of the video might have to be
//! re-encoded.
//!
//! With respect to cut list determination and selection, there are different
//! options:
//!
//! 1. Cut lists are downloaded from the cut list provider [cutlist.at](http://cutlist.at)
//!    and selected automatically
//!
//!     If multiple cut lists are available, those with a high rating are
//!    preferred.
//!
//!     Example:
//!    The path of the video to be cut and the path of the cut video are
//!    submitted as command line parameters.
//!
//!     ```edition2021
//!     fn main() {
//!         let args: Vec<String> = std::env::args().collect();
//!     
//!         let in_video = &args[1];
//!         let out_video = &args[2];
//!     
//!         if let Err(err) = otr_utils::cutting::cut(
//!             in_video,
//!             out_video,
//!             &otr_utils::cutting::CutlistCtrl::default(),
//!         ) {
//!             eprintln!("{:?}", err);
//!         }
//!     }
//!     ```
//!
//! 1. A cut list is passed explicitly to the cut function as cut list file
//!
//!     Example:
//!    The path of the video to be cut, the path of the cut video as well as
//!    the path of the cut list file are submitted as command line parameters.
//!
//!     ```edition2021
//!     fn main() {
//!         let args: Vec<String> = std::env::args().collect();
//!
//!         let in_video = &args[1];
//!         let out_video = &args[2];
//!         let cutlist = std::path::Path::new(&args[3]);
//!
//!         let ctrl = otr_utils::cutting::CutlistCtrl {
//!             access_type: otr_utils::cutting::CutlistAccessType::File(cutlist),
//!             ..Default::default()
//!         };
//!
//!         if let Err(err) = otr_utils::cutting::cut(in_video, out_video, &ctrl) {
//!             eprintln!("{:?}", err);
//!         }
//!     }
//!     ```
//!
//! 1. A cut list is passed explicitly to the cut function as string of cut
//!    intervals
//!
//!     This option can make sense if cutlist.at cannot provide a cut list for a
//!    video, and the cut intervals were determined via a video program, such as
//!    avidemux.
//!    In this case, the cut function can upload such cut lists to [cutlist.at](http://cutlist.at)
//!    to make them publicly available. This requires a registration at
//!    cutlist.at (i.e., an access token - $$FRED).
//!
//!     Example:
//!    A video is cut to its first 5 minutes, the corresponding cut list is
//!    submitted to cutlist.at with a rating of 5.
//!    The path of the video to be cut and the path of the cut video are
//!    submitted as command line parameters.
//!
//!     ```edition2021
//!     fn main() {
//!         let args: Vec<String> = std::env::args().collect();
//!
//!         let in_video = &args[1];
//!         let out_video = &args[2];
//!
//!         let ctrl = otr_utils::cutting::CutlistCtrl {
//!             submit: true,
//!             rating: 5,
//!             access_token: Some("{CUTLIST.AT-ACCESS-TOKEN}"),
//!             access_type: otr_utils::cutting::CutlistAccessType::Direct(
//!                 "times:[00:00:00.000,00:05:00.000]",
//!             ),
//!             ..Default::default()
//!         };
//!
//!         if let Err(err) = otr_utils::cutting::cut(in_video, out_video, &ctrl) {
//!             eprintln!("{:?}", err);
//!         }
//!     }
//!     ```

pub mod cutting;
pub mod decoding;
mod dirs;