bump deps, remove num rational

This commit is contained in:
jazzfool 2024-02-18 21:21:01 +11:00
parent 935d9320f9
commit 51794fc0b1
4 changed files with 2226 additions and 1635 deletions

3777
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -6,16 +6,14 @@ edition = "2018"
resolver = "2" resolver = "2"
[dependencies] [dependencies]
iced = { version = "0.3", features = ["image", "tokio"] } iced = { version = "0.12", features = ["image", "tokio"] }
iced_native = "0.3" iced_native = "0.10"
gstreamer = "0.17" gstreamer = "0.22"
gstreamer-app = "0.17" # appsink gstreamer-app = "0.22" # appsink
glib = "0.14" # gobject traits and error type glib = "0.19" # gobject traits and error type
tokio = { version = "1", features = ["time"] } tokio = { version = "1", features = ["time"] }
thiserror = "1" thiserror = "1"
url = "2" # media uri url = "2" # media uri
num-rational = "0.4" # framerates come in rationals
num-traits = "0.2" # convert rationals to floats (ToPrimitive)
[package.metadata.nix] [package.metadata.nix]
systems = ["x86_64-linux"] systems = ["x86_64-linux"]

View file

@ -1,5 +1,7 @@
use iced::{ use iced::{
button, executor, Application, Button, Column, Command, Element, Row, Subscription, Text, executor,
widget::{Button, Column, Row, Text},
Application, Command, Element, Subscription, Theme,
}; };
use iced_video_player::{VideoPlayer, VideoPlayerMessage}; use iced_video_player::{VideoPlayer, VideoPlayerMessage};
@ -16,14 +18,13 @@ enum Message {
struct App { struct App {
video: VideoPlayer, video: VideoPlayer,
pause_btn: button::State,
loop_btn: button::State,
} }
impl Application for App { impl Application for App {
type Executor = executor::Default; type Executor = executor::Default;
type Message = Message; type Message = Message;
type Flags = (); type Flags = ();
type Theme = Theme;
fn new(_flags: ()) -> (Self, Command<Message>) { fn new(_flags: ()) -> (Self, Command<Message>) {
let video = VideoPlayer::new( let video = VideoPlayer::new(
@ -39,21 +40,14 @@ impl Application for App {
false, false,
) )
.unwrap(); .unwrap();
( (App { video }, Command::none())
App {
video,
pause_btn: Default::default(),
loop_btn: Default::default(),
},
Command::none(),
)
} }
fn title(&self) -> String { fn title(&self) -> String {
String::from("Video Player") String::from("Video Player")
} }
fn update(&mut self, message: Message, _: &mut iced::Clipboard) -> Command<Message> { fn update(&mut self, message: Message) -> Command<Message> {
match message { match message {
Message::TogglePause => { Message::TogglePause => {
self.video.set_paused(!self.video.paused()); self.video.set_paused(!self.video.paused());
@ -73,28 +67,26 @@ impl Application for App {
self.video.subscription().map(Message::VideoPlayerMessage) self.video.subscription().map(Message::VideoPlayerMessage)
} }
fn view(&mut self) -> Element<Message> { fn view(&self) -> Element<Message> {
Column::new() Column::new()
.push(self.video.frame_view()) .push(self.video.frame_view())
.push( .push(
Row::new() Row::new()
.spacing(5) .spacing(5)
.push( .push(
Button::new( Button::new(Text::new(if self.video.paused() {
&mut self.pause_btn, "Play"
Text::new(if self.video.paused() { "Play" } else { "Pause" }), } else {
) "Pause"
}))
.on_press(Message::TogglePause), .on_press(Message::TogglePause),
) )
.push( .push(
Button::new( Button::new(Text::new(if self.video.looping() {
&mut self.loop_btn, "Disable Loop"
Text::new(if self.video.looping() { } else {
"Disable Loop" "Enable Loop"
} else { }))
"Enable Loop"
}),
)
.on_press(Message::ToggleLoop), .on_press(Message::ToggleLoop),
) )
.push(Text::new(format!( .push(Text::new(format!(

View file

@ -1,8 +1,10 @@
use gst::prelude::*; use gst::prelude::*;
use gstreamer as gst; use gstreamer as gst;
use gstreamer_app as gst_app; use gstreamer_app as gst_app;
use iced::{image as img, Command, Image, Subscription}; use iced::{
use num_traits::ToPrimitive; widget::{image as img, Image},
Command, Subscription,
};
use std::convert::identity; use std::convert::identity;
use std::future; use std::future;
use std::sync::{mpsc, Arc, Mutex}; use std::sync::{mpsc, Arc, Mutex};
@ -24,7 +26,7 @@ impl From<Position> for gst::GenericFormattedValue {
fn from(pos: Position) -> Self { fn from(pos: Position) -> Self {
match pos { match pos {
Position::Time(t) => gst::ClockTime::from_nseconds(t.as_nanos() as _).into(), Position::Time(t) => gst::ClockTime::from_nseconds(t.as_nanos() as _).into(),
Position::Frame(f) => gst::format::Default(f).into(), Position::Frame(f) => gst::format::Default::from_u64(f).into(),
} }
} }
} }
@ -113,10 +115,10 @@ impl VideoPlayer {
pub fn new(uri: &url::Url, live: bool) -> Result<Self, Error> { pub fn new(uri: &url::Url, live: bool) -> Result<Self, Error> {
gst::init()?; gst::init()?;
let source = gst::parse_launch(&format!("playbin uri=\"{}\" video-sink=\"videoconvert ! videoscale ! appsink name=app_sink caps=video/x-raw,format=BGRA,pixel-aspect-ratio=1/1\"", uri.as_str()))?; let source = gst::parse::launch(&format!("playbin uri=\"{}\" video-sink=\"videoconvert ! videoscale ! appsink name=app_sink caps=video/x-raw,format=RGBA,pixel-aspect-ratio=1/1\"", uri.as_str()))?;
let source = source.downcast::<gst::Bin>().unwrap(); let source = source.downcast::<gst::Bin>().unwrap();
let video_sink: gst::Element = source.property("video-sink").unwrap().get().unwrap(); let video_sink: gst::Element = source.property("video-sink");
let pad = video_sink.pads().get(0).cloned().unwrap(); let pad = video_sink.pads().get(0).cloned().unwrap();
let pad = pad.dynamic_cast::<gst::GhostPad>().unwrap(); let pad = pad.dynamic_cast::<gst::GhostPad>().unwrap();
let bin = pad let bin = pad
@ -193,11 +195,7 @@ impl VideoPlayer {
width, width,
height, height,
framerate: num_rational::Rational32::new( framerate: framerate.numer() as f64 / framerate.denom() as f64,
*framerate.numer() as _,
*framerate.denom() as _,
)
.to_f64().unwrap(/* if the video framerate is bad then it would've been implicitly caught far earlier */),
duration, duration,
frame, frame,
@ -227,13 +225,13 @@ impl VideoPlayer {
/// ///
/// This uses a linear scale, for example `0.5` is perceived as half as loud. /// This uses a linear scale, for example `0.5` is perceived as half as loud.
pub fn set_volume(&mut self, volume: f64) { pub fn set_volume(&mut self, volume: f64) {
self.source.set_property("volume", &volume).unwrap(/* this property is guaranteed to exist */); self.source.set_property("volume", &volume);
} }
/// Set if the audio is muted or not, without changing the volume. /// Set if the audio is muted or not, without changing the volume.
pub fn set_muted(&mut self, muted: bool) { pub fn set_muted(&mut self, muted: bool) {
self.muted = muted; self.muted = muted;
self.source.set_property("mute", &muted).unwrap(); self.source.set_property("mute", &muted);
} }
/// Get if the audio is muted or not. /// Get if the audio is muted or not.
@ -286,8 +284,10 @@ impl VideoPlayer {
/// Jumps to a specific position in the media. /// Jumps to a specific position in the media.
/// The seeking is not perfectly accurate. /// The seeking is not perfectly accurate.
pub fn seek(&mut self, position: impl Into<Position>) -> Result<(), Error> { pub fn seek(&mut self, position: impl Into<Position>) -> Result<(), Error> {
self.source self.source.seek_simple(
.seek_simple(gst::SeekFlags::FLUSH, position.into())?; gst::SeekFlags::FLUSH,
gst::GenericFormattedValue::from(position.into()),
)?;
Ok(()) Ok(())
} }
@ -392,7 +392,7 @@ impl VideoPlayer {
} }
/// Wrap the output of `frame_image` in an `Image` widget. /// Wrap the output of `frame_image` in an `Image` widget.
pub fn frame_view(&mut self) -> Image { pub fn frame_view(&self) -> Image<img::Handle> {
Image::new(self.frame_image()) Image::new(self.frame_image())
} }