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
|
/*
This file is part of jellything (https://codeberg.org/metamuffin/jellything)
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2024 metamuffin <metamuffin.org>
*/
pub mod extract;
pub mod import;
pub mod remux;
pub mod seek_index;
pub mod segment_extractor;
pub mod snippet;
pub mod trim_writer;
pub use remux::remux_stream_into;
pub use snippet::write_snippet_into;
use jellycommon::{SourceTrack, SourceTrackKind};
use jellymatroska::{Master, MatroskaTag};
pub fn ebml_header(webm: bool) -> MatroskaTag {
MatroskaTag::Ebml(Master::Collected(vec![
MatroskaTag::EbmlVersion(1),
MatroskaTag::EbmlReadVersion(1),
MatroskaTag::EbmlMaxIdLength(4),
MatroskaTag::EbmlMaxSizeLength(8),
MatroskaTag::DocType(if webm {
"webm".to_string()
} else {
"matroska".to_string()
}),
MatroskaTag::DocTypeVersion(4),
MatroskaTag::DocTypeReadVersion(2),
]))
}
pub fn ebml_segment_info(title: String, duration: f64) -> MatroskaTag {
MatroskaTag::Info(Master::Collected(vec![
MatroskaTag::TimestampScale(1_000_000),
MatroskaTag::Duration(duration * 1000.0),
MatroskaTag::Title(title),
MatroskaTag::MuxingApp("jellyremux".to_string()),
MatroskaTag::WritingApp("jellything".to_string()),
]))
}
pub fn ebml_track_entry(
number: u64,
track: &SourceTrack,
codec_private: Option<Vec<u8>>,
) -> MatroskaTag {
let mut els = vec![
MatroskaTag::TrackNumber(number),
MatroskaTag::TrackUID(number),
MatroskaTag::FlagLacing(0),
MatroskaTag::Language(track.language.clone()),
MatroskaTag::CodecID(track.codec.clone()),
];
if let Some(d) = &track.default_duration {
els.push(MatroskaTag::DefaultDuration(*d));
}
match track.kind {
SourceTrackKind::Video {
width,
height,
fps: _,
} => {
els.push(MatroskaTag::TrackType(1));
els.push(MatroskaTag::Video(Master::Collected(vec![
MatroskaTag::PixelWidth(width),
MatroskaTag::PixelHeight(height),
])))
}
SourceTrackKind::Audio {
channels,
sample_rate,
bit_depth,
} => {
els.push(MatroskaTag::TrackType(2));
els.push(MatroskaTag::Audio(Master::Collected(vec![
MatroskaTag::SamplingFrequency(sample_rate),
MatroskaTag::Channels(channels.try_into().unwrap()),
])));
els.push(MatroskaTag::BitDepth(bit_depth.try_into().unwrap()));
}
SourceTrackKind::Subtitles => {
els.push(MatroskaTag::TrackType(19));
}
}
if let Some(d) = &codec_private {
els.push(MatroskaTag::CodecPrivate(d.clone()));
}
MatroskaTag::TrackEntry(Master::Collected(els))
}
|