use wry::http::Response;
fn main() -> wry::Result<()> {
use http_range::HttpRange;
use std::{
fs::{canonicalize, File},
io::{Read, Seek, SeekFrom},
path::PathBuf,
process::{Command, Stdio},
};
use wry::{
application::{
event::{Event, StartCause, WindowEvent},
event_loop::{ControlFlow, EventLoop},
window::WindowBuilder,
},
http::{header::CONTENT_TYPE, status::StatusCode},
webview::WebViewBuilder,
};
let video_file = PathBuf::from("examples/test_video.mp4");
let video_url =
"http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4";
if !video_file.exists() {
println!("Downloading {}", video_url);
let status = Command::new("curl")
.arg("-L")
.arg("-o")
.arg(&video_file)
.arg(video_url)
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.output()
.unwrap();
assert!(status.status.success());
assert!(video_file.exists());
}
let event_loop = EventLoop::new();
let window = WindowBuilder::new()
.with_title("Hello World")
.build(&event_loop)
.unwrap();
let _webview = WebViewBuilder::new(window)
.unwrap()
.with_custom_protocol("wry".into(), move |request| {
let path = &request.uri().path()[1..];
let mut content = File::open(canonicalize(path)?)?;
let mut status_code = StatusCode::OK;
let mut buf = Vec::new();
let mimetype = if path.ends_with(".html") {
"text/html"
} else if path.ends_with(".mp4") {
"video/mp4"
} else {
unimplemented!();
};
let mut response = Response::builder();
if let Some(range) = request.headers().get("range") {
let file_size = content.metadata().unwrap().len();
let range = HttpRange::parse(range.to_str().unwrap(), file_size).unwrap();
let first_range = range.first();
if let Some(range) = first_range {
let mut real_length = range.length;
if range.length > file_size / 3 {
real_length = 1024 * 400;
}
let last_byte = range.start + real_length - 1;
status_code = StatusCode::PARTIAL_CONTENT;
response = response.header("Connection", "Keep-Alive");
response = response.header("Accept-Ranges", "bytes");
response = response.header("Content-Length", real_length);
response = response.header(
"Content-Range",
format!("bytes {}-{}/{}", range.start, last_byte, file_size),
);
content.seek(SeekFrom::Start(range.start))?;
content.take(real_length).read_to_end(&mut buf)?;
} else {
content.read_to_end(&mut buf)?;
}
} else {
content.read_to_end(&mut buf)?;
}
response
.header(CONTENT_TYPE, mimetype)
.status(status_code)
.body(buf.into())
.map_err(Into::into)
})
.with_url("wry://localhost/examples/stream.html")?
.build()?;
event_loop.run(move |event, _, control_flow| {
*control_flow = ControlFlow::Wait;
match event {
Event::NewEvents(StartCause::Init) => println!("Wry application started!"),
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => *control_flow = ControlFlow::Exit,
_ => {}
}
});
}