youtube_dl_parser/
lib.rs

1/*!
2Crate `youtube-dl-parser` runs youtube-dl and parses its download output.
3
4# Usage
5To use this crate, add `youtube-dl-parser` as a dependency to your project's `Cargo.toml`:
6
7```toml
8[dependencies]
9youtube-dl-parser = "0.2.0"
10```
11
12# Important
13In order to use the functions provided by the library, [youtube-dl](https://github.com/ytdl-org/youtube-dl)
14and [FFmpeg](https://github.com/FFmpeg/FFmpeg) must be added to PATH or be in the current directory.
15
16# Work in progress
17
18The crate is currently work in progress and only parses the output of YouTube mp3 and mp4 downloads.
19
20# Example: Start a youtube-dl mp3 download and match on its output:
21```
22use youtube_dl_parser::expressions::mp3_download_expression;
23use youtube_dl_parser::reader::{OutputReader, ParsedOutputReader};
24use youtube_dl_parser::state::parsed_state::{
25    DeletingState, DownloadState, ErrorState, FFmpegState, ParsedState, YoutubeState,
26};
27use youtube_dl_parser::state::ParsedOutputState;
28
29let youtube_dl_path = "youtube-dl.exe";
30let url = "https://www.youtube.com/watch?v=tPEE9ZwTmy0";
31let downloads_folder = "downloads";
32
33let big_cmd = mp3_download_expression(youtube_dl_path, url, downloads_folder);
34let stdout = big_cmd
35    .stderr_to_stdout()
36    .reader()
37    .expect("Unable to execute youtube-dl");
38
39let output_reader = OutputReader::new(stdout);
40
41let parsed_output_reader = ParsedOutputReader::new(output_reader);
42
43for parsed_state in parsed_output_reader {
44    match parsed_state {
45        ParsedOutputState::Parsed(parsed_state) => match parsed_state {
46            ParsedState::Youtube(youtube_state) => match youtube_state {
47                YoutubeState::Initiating => {
48                    println!("Initiating youtube download");
49                }
50                YoutubeState::ParseError(parse_error) => {
51                    println!("YouTube state parse error: {parse_error}");
52                }
53            },
54            ParsedState::Download(download_state) => match download_state {
55                DownloadState::Destination(destination) => {
56                    println!("Starting download with destination: {destination}");
57                }
58                DownloadState::Resuming(byte) => {
59                    println!("Resuming download from byte: {byte}");
60                }
61                DownloadState::Downloading(progress, total_size, download_speed, eta) => {
62                    println!("Progress: {progress}%, Total size: {total_size} bytes, Download speed: {download_speed} bytes per second, ETA: {eta} seconds");
63                }
64                DownloadState::Downloaded(progress, total_size, completion_time) => {
65                    println!("Download finished at {progress}% of {total_size} bytes in {completion_time} seconds");
66                }
67                DownloadState::ParseError(err) => {
68                    println!("Download state parse error: {err}")
69                }
70            },
71            ParsedState::FFMpeg(ffmpeg_state) => match ffmpeg_state {
72                FFmpegState::Destination(destination) => {
73                    println!("Using ffmpeg with file destination: {destination}");
74                }
75                FFmpegState::ParseError(parse_error) => {
76                    println!("FFmpeg state parse error: {parse_error}");
77                }
78            },
79            ParsedState::Error(error_state) => match error_state {
80                ErrorState::Error(error) => {
81                    println!("Error occurred: {error}")
82                }
83            },
84            ParsedState::Deleting(deleting_state) => match deleting_state {
85                DeletingState::DeletingTemporaryFile(path) => {
86                    println!("Deleting temporary file: {path}");
87                }
88                DeletingState::ParseError(parse_error) => {
89                    println!("Deleting state parse error: {parse_error}");
90                }
91            },
92            ParsedState::None(output) => {
93                println!("No state detected: {output}")
94            }
95            ParsedState::Unknown(output) => {
96                println!("Unknown output state: {output}");
97            }
98            ParsedState::ParseError(parse_error) => {
99                println!("Output parse error: {parse_error}");
100            }
101        },
102        ParsedOutputState::Finished => {
103            println!("Output finished");
104        }
105        ParsedOutputState::Error(parsed_error_state) => {
106            println!(
107                "Exit code: {:?}, Error: {}",
108                parsed_error_state.exit_code, parsed_error_state.error
109            );
110        }
111    }
112}
113```
114
115 */
116
117/// Duct expressions for mp3 and mp4 youtube-dl downloads.
118pub mod expressions;
119/// Parsed and raw output readers
120pub mod reader;
121/// The different states the readers could output
122pub mod state;