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//! let args: Vec<String> = std::env::args().collect();
24//!
25//! let in_video = &args[1];
26//! let out_video = &args[2];
27//! let user = &args[3];
28//! let password = &args[4];
29//!
30//! if let Err(err) = otr_utils::decoding::decode(in_video, out_video, user, password) {
31//! eprintln!("{:?}", err);
32//! }
33//! ```
34//!
35//! ## Cutting
36//!
37//! Cutting of decoded videos is done by using [FFmpeg](https://ffmpeg.org/) together
38//! with [FFMS2](https://github.com/FFMS/ffms2). It is done **accurate to frames**.
39//! I.e., even if a boundary of a cut interval is not at a key frame, cutting is done
40//! exactly at that boundary. To achieve this, parts of the video might have to be
41//! re-encoded.
42//!
43//! With respect to cut list determination and selection, there are different
44//! options:
45//!
46//! 1. Cut lists are downloaded from the cut list provider [cutlist.at](http://cutlist.at)
47//! and selected automatically
48//!
49//! If multiple cut lists are available, those with a high rating are
50//! preferred.
51//!
52//! Example:
53//! The path of the video to be cut and the path of the cut video are
54//! submitted as command line parameters.
55//!
56//! ```edition2021
57//! fn main() {
58//! let args: Vec<String> = std::env::args().collect();
59//!
60//! let in_video = &args[1];
61//! let out_video = &args[2];
62//!
63//! if let Err(err) = otr_utils::cutting::cut(
64//! in_video,
65//! out_video,
66//! &otr_utils::cutting::CutlistCtrl::default(),
67//! ) {
68//! eprintln!("{:?}", err);
69//! }
70//! }
71//! ```
72//!
73//! 1. A cut list is passed explicitly to the cut function as cut list file
74//!
75//! Example:
76//! The path of the video to be cut, the path of the cut video as well as
77//! the path of the cut list file are submitted as command line parameters.
78//!
79//! ```edition2021
80//! fn main() {
81//! let args: Vec<String> = std::env::args().collect();
82//!
83//! let in_video = &args[1];
84//! let out_video = &args[2];
85//! let cutlist = std::path::Path::new(&args[3]);
86//!
87//! let ctrl = otr_utils::cutting::CutlistCtrl {
88//! access_type: otr_utils::cutting::CutlistAccessType::File(cutlist),
89//! ..Default::default()
90//! };
91//!
92//! if let Err(err) = otr_utils::cutting::cut(in_video, out_video, &ctrl) {
93//! eprintln!("{:?}", err);
94//! }
95//! }
96//! ```
97//!
98//! 1. A cut list is passed explicitly to the cut function as string of cut
99//! intervals
100//!
101//! This option can make sense if cutlist.at cannot provide a cut list for a
102//! video, and the cut intervals were determined via a video program, such as
103//! avidemux.
104//! In this case, the cut function can upload such cut lists to [cutlist.at](http://cutlist.at)
105//! to make them publicly available. This requires a registration at
106//! cutlist.at (i.e., an access token - $$FRED).
107//!
108//! Example:
109//! A video is cut to its first 5 minutes, the corresponding cut list is
110//! submitted to cutlist.at with a rating of 5.
111//! The path of the video to be cut and the path of the cut video are
112//! submitted as command line parameters.
113//!
114//! ```edition2021
115//! fn main() {
116//! let args: Vec<String> = std::env::args().collect();
117//!
118//! let in_video = &args[1];
119//! let out_video = &args[2];
120//!
121//! let ctrl = otr_utils::cutting::CutlistCtrl {
122//! submit: true,
123//! rating: 5,
124//! access_token: Some("{CUTLIST.AT-ACCESS-TOKEN}"),
125//! access_type: otr_utils::cutting::CutlistAccessType::Direct(
126//! "times:[00:00:00.000,00:05:00.000]",
127//! ),
128//! ..Default::default()
129//! };
130//!
131//! if let Err(err) = otr_utils::cutting::cut(in_video, out_video, &ctrl) {
132//! eprintln!("{:?}", err);
133//! }
134//! }
135//! ```
136
137pub mod cutting;
138pub mod decoding;
139mod dirs;