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
//! `OxiMedia` Container Layer
//!
//! Container format handling with resilient parsing for:
//! - Matroska (.mkv) / `WebM` (.webm)
//! - Ogg (.ogg, .opus, .oga)
//! - FLAC (.flac)
//! - WAV (.wav)
//! - MP4 (.mp4) - AV1/VP9 only
//! - MPEG-TS (.ts, .m2ts) - AV1/VP9/VP8/Opus/FLAC only
//! - YUV4MPEG2 (.y4m) - Raw uncompressed video
//!
//! # Overview
//!
//! This crate provides demuxers and muxers for media container formats.
//! A demuxer reads a container file and extracts compressed packets,
//! while a muxer combines compressed packets into a container file.
//!
//! # Key Types
//!
//! - [`ContainerFormat`] - Enumeration of supported container formats
//! - [`probe_format`] - Detect container format from magic bytes
//! - [`Packet`] - Compressed media packet with timestamps
//! - [`StreamInfo`] - Information about a stream (codec, dimensions, etc.)
//! - [`Demuxer`] - Trait for container demuxers
//! - [`Muxer`] - Trait for container muxers
//!
//! # Demuxing Example
//!
//! ```ignore
//! use oximedia_container::{probe_format, demux::MatroskaDemuxer, Demuxer};
//! use oximedia_io::FileSource;
//!
//! // Detect format from file header
//! let mut source = FileSource::open("video.mkv").await?;
//! let mut buf = [0u8; 12];
//! source.read(&mut buf).await?;
//! let format = probe_format(&buf)?;
//! println!("Format: {:?}", format.format);
//!
//! // Demux the file
//! source.seek(std::io::SeekFrom::Start(0)).await?;
//! let mut demuxer = MatroskaDemuxer::new(source);
//! demuxer.probe().await?;
//!
//! for stream in demuxer.streams() {
//! println!("Stream {}: {:?}", stream.index, stream.codec);
//! }
//!
//! while let Ok(packet) = demuxer.read_packet().await {
//! println!("Packet: stream={}, size={}, keyframe={}",
//! packet.stream_index, packet.size(), packet.is_keyframe());
//! }
//! ```
//!
//! # Muxing Example
//!
//! ```ignore
//! use oximedia_container::mux::{MatroskaMuxer, Muxer, MuxerConfig};
//!
//! let config = MuxerConfig::new()
//! .with_title("My Video");
//!
//! let mut muxer = MatroskaMuxer::new(sink, config);
//! muxer.add_stream(video_info)?;
//! muxer.add_stream(audio_info)?;
//!
//! muxer.write_header().await?;
//!
//! for packet in packets {
//! muxer.write_packet(&packet).await?;
//! }
//!
//! muxer.write_trailer().await?;
//! ```
//!
//! # Metadata Editing Example
//!
//! ```ignore
//! use oximedia_container::metadata::MetadataEditor;
//!
//! let mut editor = MetadataEditor::open("audio.flac").await?;
//!
//! // Read tags
//! if let Some(title) = editor.get_text("TITLE") {
//! println!("Title: {}", title);
//! }
//!
//! // Modify tags
//! editor.set("TITLE", "New Title");
//! editor.set("ARTIST", "New Artist");
//!
//! // Save changes
//! editor.save().await?;
//! ```
// Re-export main types at crate root
pub use Demuxer;
pub use ContainerFormat;
pub use ;
pub use ;
pub use ;
pub use ;
pub use ;