otr_utils/
lib.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// 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
//! fn main() {
//!     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;