GStramer implementation, it plays videos, nice!
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
ci/woodpecker/pr/woodpecker Pipeline failed

This commit is contained in:
Midou36O 2022-09-21 01:01:37 +01:00
parent 88f3cae2cf
commit cbc302914a
Signed by: midou
GPG Key ID: 08063D5407090BC2
3 changed files with 105 additions and 9 deletions

View File

@ -11,6 +11,10 @@ adw = { version = "0.1.1", package = "libadwaita" }
invidious = "0.3.2" invidious = "0.3.2"
gtk-ui-builder = "0.2.0" gtk-ui-builder = "0.2.0"
serde_json = "1.0" serde_json = "1.0"
gst = { version = "0.18.8", package = "gstreamer" }
anyhow = "1.0.65"
glib = "0.15.12"
gst-plugin-reqwest = "0.8.0"
[profile.release] [profile.release]
strip = true strip = true

View File

@ -3,11 +3,10 @@ use std::error::Error;
//use serde::{Deserialize, Serialize}; //use serde::{Deserialize, Serialize};
//use serde_json::Result; //use serde_json::Result;
pub fn inv() -> Result<(), Box<dyn Error>> {
pub fn inv() -> Result<String, Box<dyn Error>> {
let client = Client::new(String::from("https://invidious.projectsegfau.lt")); let client = Client::new(String::from("https://invidious.projectsegfau.lt"));
let search_results = client.search(Some("q=rust programming"))?.items; let output = &client.video("5C_HPTJg5ek", None)?.format_streams[2].url;
let video = client.video("5C_HPTJg5ek", None)?; println!("{}", output);
//println!("{:?}", video); Ok(output.to_string())
println!("{:?}", video.format_streams[2].url);
Ok(())
} }

View File

@ -6,7 +6,10 @@ use std::fs::File;
use std::path::Path; use std::path::Path;
use gtk::prelude::*; use gtk::prelude::*;
use gtk::{self, ApplicationWindow, Button, prelude::*, ListBox, FlowBox, PolicyType, ScrolledWindow, Box, Orientation, Align::*}; use gtk::{self, ApplicationWindow, Button, prelude::*, ListBox, FlowBox, PolicyType, ScrolledWindow, Box, Orientation, Align::*};
use crate::inv::inv; use gst::prelude::*;
use std::io::Write;
use anyhow::Error;
use crate::inv::*;
mod inv; mod inv;
@ -19,9 +22,15 @@ fn main() {
// Connect to "activate" signal of `app` // Connect to "activate" signal of `app`
app.connect_activate(build_ui); app.connect_activate(build_ui);
//print!("{:?}", output); //print!("{:?}", output);
// Run the application // Run the application
match VidPlayer() {
Ok(_) => {}
Err(err) => eprintln!("Failed: {}", err),
}
app.run(); app.run();
} }
@ -85,3 +94,87 @@ fn build_ui(app: &Application) {
//fn trig_play() { //fn trig_play() {
// let trigger = // let trigger =
//} //}
use gst::prelude::*;
fn VidPlayer() -> Result<(), Error> {
// Initialize GStreamer
gst::init()?;
// Build the pipeline
//let uri =
//"https://www.freedesktop.org/software/gstreamer-sdk/data/media/sintel_trailer-480p.webm";
let uri = inv().unwrap();
println!("{:?}", uri);
let pipeline = gst::parse_launch(&format!("playbin uri={:?}", uri))?;
// Start playing
let res = pipeline.set_state(gst::State::Playing)?;
let is_live = res == gst::StateChangeSuccess::NoPreroll;
let main_loop = glib::MainLoop::new(None, false);
let main_loop_clone = main_loop.clone();
let pipeline_weak = pipeline.downgrade();
let bus = pipeline.bus().expect("Pipeline has no bus");
bus.add_watch(move |_, msg| {
let pipeline = match pipeline_weak.upgrade() {
Some(pipeline) => pipeline,
None => return glib::Continue(true),
};
let main_loop = &main_loop_clone;
match msg.view() {
gst::MessageView::Error(err) => {
println!(
"Error from {:?}: {} ({:?})",
err.src().map(|s| s.path_string()),
err.error(),
err.debug()
);
let _ = pipeline.set_state(gst::State::Ready);
main_loop.quit();
}
gst::MessageView::Eos(..) => {
// end-of-stream
let _ = pipeline.set_state(gst::State::Ready);
main_loop.quit();
}
gst::MessageView::Buffering(buffering) => {
// If the stream is live, we do not care about buffering
if is_live {
return glib::Continue(true);
}
let percent = buffering.percent();
print!("Buffering ({}%)\r", percent);
match std::io::stdout().flush() {
Ok(_) => {}
Err(err) => eprintln!("Failed: {}", err),
};
// Wait until buffering is complete before start/resume playing
if percent < 100 {
let _ = pipeline.set_state(gst::State::Paused);
} else {
let _ = pipeline.set_state(gst::State::Playing);
}
}
gst::MessageView::ClockLost(_) => {
// Get a new clock
let _ = pipeline.set_state(gst::State::Paused);
let _ = pipeline.set_state(gst::State::Playing);
}
_ => (),
}
glib::Continue(true)
})
.expect("Failed to add bus watch");
main_loop.run();
bus.remove_watch()?;
pipeline.set_state(gst::State::Null)?;
Ok(())
}