otr_utils/lib.rs
1// SPDX-FileCopyrightText: 2024 Michael Picht <mipi@fsfe.org>
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5//! # otr-utils
6//!
7//! otr-utils provides tools to decode and cut video files from [Online TV Recorder](https://www.onlinetvrecorder.com/)
8//! (OTR).
9//!
10//! ## Decoding
11//!
12//! Decoding of OTRKEY files (i.e., encoded video files downloaded from OTR) is
13//! supported. The decoding functionality is based on the work of eddy14, who
14//! reverse-engineered the OTRKEY file format, see [his blog post](https://pyropeter.eu/41yd.de/blog/2010/04/18/otrkey-breaker/)
15//! [German, mirrored by [PyroPeter](https://github.com/pyropeter)].
16//!
17//! Example:
18//! The path of the video to be decoded (i.e., the OTRKEY file), the path of the
19//! decoded video, as well as user and password for OnlineTVRecorder are
20//! submitted as command line parameters.
21//!
22//! ```edition2021
23//! fn main() {
24//! let args: Vec<String> = std::env::args().collect();
25//!
26//! let in_video = &args[1];
27//! let out_video = &args[2];
28//! let user = &args[3];
29//! let password = &args[4];
30//!
31//! if let Err(err) = otr_utils::decoding::decode(in_video, out_video, user, password) {
32//! eprintln!("{:?}", err);
33//! }
34//! }
35//! ```
36//!
37//! ## Cutting
38//!
39//! Cutting of decoded videos is done by using [FFmpeg](https://ffmpeg.org/) together
40//! with [FFMS2](https://github.com/FFMS/ffms2). It is done **accurate to frames**.
41//! I.e., even if a boundary of a cut interval is not at a key frame, cutting is done
42//! exactly at that boundary. To achieve this, parts of the video might have to be
43//! re-encoded.
44//!
45//! With respect to cut list determination and selection, there are different
46//! options:
47//!
48//! 1. Cut lists are downloaded from the cut list provider [cutlist.at](http://cutlist.at)
49//! and selected automatically
50//!
51//! If multiple cut lists are available, those with a high rating are
52//! preferred.
53//!
54//! Example:
55//! The path of the video to be cut and the path of the cut video are
56//! submitted as command line parameters.
57//!
58//! ```edition2021
59//! fn main() {
60//! let args: Vec<String> = std::env::args().collect();
61//!
62//! let in_video = &args[1];
63//! let out_video = &args[2];
64//!
65//! if let Err(err) = otr_utils::cutting::cut(
66//! in_video,
67//! out_video,
68//! &otr_utils::cutting::CutlistCtrl::default(),
69//! ) {
70//! eprintln!("{:?}", err);
71//! }
72//! }
73//! ```
74//!
75//! 1. A cut list is passed explicitly to the cut function as cut list file
76//!
77//! Example:
78//! The path of the video to be cut, the path of the cut video as well as
79//! the path of the cut list file are submitted as command line parameters.
80//!
81//! ```edition2021
82//! fn main() {
83//! let args: Vec<String> = std::env::args().collect();
84//!
85//! let in_video = &args[1];
86//! let out_video = &args[2];
87//! let cutlist = std::path::Path::new(&args[3]);
88//!
89//! let ctrl = otr_utils::cutting::CutlistCtrl {
90//! access_type: otr_utils::cutting::CutlistAccessType::File(cutlist),
91//! ..Default::default()
92//! };
93//!
94//! if let Err(err) = otr_utils::cutting::cut(in_video, out_video, &ctrl) {
95//! eprintln!("{:?}", err);
96//! }
97//! }
98//! ```
99//!
100//! 1. A cut list is passed explicitly to the cut function as string of cut
101//! intervals
102//!
103//! This option can make sense if cutlist.at cannot provide a cut list for a
104//! video, and the cut intervals were determined via a video program, such as
105//! avidemux.
106//! In this case, the cut function can upload such cut lists to [cutlist.at](http://cutlist.at)
107//! to make them publicly available. This requires a registration at
108//! cutlist.at (i.e., an access token - $$FRED).
109//!
110//! Example:
111//! A video is cut to its first 5 minutes, the corresponding cut list is
112//! submitted to cutlist.at with a rating of 5.
113//! The path of the video to be cut and the path of the cut video are
114//! submitted as command line parameters.
115//!
116//! ```edition2021
117//! fn main() {
118//! let args: Vec<String> = std::env::args().collect();
119//!
120//! let in_video = &args[1];
121//! let out_video = &args[2];
122//!
123//! let ctrl = otr_utils::cutting::CutlistCtrl {
124//! submit: true,
125//! rating: 5,
126//! access_token: Some("{CUTLIST.AT-ACCESS-TOKEN}"),
127//! access_type: otr_utils::cutting::CutlistAccessType::Direct(
128//! "times:[00:00:00.000,00:05:00.000]",
129//! ),
130//! ..Default::default()
131//! };
132//!
133//! if let Err(err) = otr_utils::cutting::cut(in_video, out_video, &ctrl) {
134//! eprintln!("{:?}", err);
135//! }
136//! }
137//! ```
138
139pub mod cutting;
140pub mod decoding;
141mod dirs;