PlayerWidget: Use the Gtk Main Context for the gst_player as well.
There is no longer a need for sending stuff to the main-thread `Action` channel anymore thanks to this.
This commit is contained in:
parent
0686fca3b0
commit
eeef0d13ff
@ -5,7 +5,6 @@ use gio::{
|
||||
SimpleAction, SimpleActionExt,
|
||||
};
|
||||
use glib;
|
||||
use gst_player;
|
||||
use gtk;
|
||||
use gtk::prelude::*;
|
||||
use gtk::SettingsExt as GtkSettingsExt;
|
||||
@ -19,7 +18,6 @@ use stacks::{Content, PopulatedState};
|
||||
use utils;
|
||||
use widgets::appnotif::{InAppNotification, UndoState};
|
||||
use widgets::player;
|
||||
use widgets::player::PlayerExt;
|
||||
use widgets::{about_dialog, mark_all_notif, remove_show_notif};
|
||||
|
||||
use std::rc::Rc;
|
||||
@ -57,9 +55,6 @@ pub enum Action {
|
||||
RemoveShow(Arc<Podcast>),
|
||||
ErrorNotification(String),
|
||||
InitEpisode(i32),
|
||||
PlayerDurationChanged(player::Duration),
|
||||
PlayerPositionUpdated(player::Position),
|
||||
PlayerEndofStream(gst_player::Player),
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -138,7 +133,7 @@ impl App {
|
||||
window.show_all();
|
||||
window.activate();
|
||||
|
||||
gtk::timeout_add(15, clone!(sender, receiver => move || {
|
||||
gtk::timeout_add(25, clone!(sender, receiver => move || {
|
||||
// Uses receiver, content, header, sender, overlay, playback
|
||||
match receiver.try_recv() {
|
||||
Ok(Action::RefreshAllViews) => content.update(),
|
||||
@ -196,9 +191,6 @@ impl App {
|
||||
notif.show(&overlay);
|
||||
},
|
||||
Ok(Action::InitEpisode(rowid)) => player.initialize_episode(rowid).unwrap(),
|
||||
Ok(Action::PlayerDurationChanged(dur)) => player.timer.on_duration_changed(dur),
|
||||
Ok(Action::PlayerPositionUpdated(pos)) => player.timer.on_position_updated(pos),
|
||||
Ok(Action::PlayerEndofStream(_)) => player.stop(),
|
||||
Err(_) => (),
|
||||
}
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@ use glib::SignalHandlerId;
|
||||
use chrono::NaiveTime;
|
||||
use crossbeam_channel::Sender;
|
||||
use failure::Error;
|
||||
use send_cell::SendCell;
|
||||
|
||||
use hammond_data::{dbqueries, USER_AGENT};
|
||||
use hammond_data::{EpisodeWidgetQuery, PodcastCoverQuery};
|
||||
@ -23,12 +24,12 @@ use std::path::Path;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub enum SeekDirection {
|
||||
enum SeekDirection {
|
||||
Backwards,
|
||||
Forward,
|
||||
}
|
||||
|
||||
pub trait PlayerExt {
|
||||
trait PlayerExt {
|
||||
fn play(&self);
|
||||
fn pause(&self);
|
||||
fn stop(&self);
|
||||
@ -72,7 +73,7 @@ impl PlayerInfo {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PlayerTimes {
|
||||
struct PlayerTimes {
|
||||
container: gtk::Box,
|
||||
progressed: gtk::Label,
|
||||
duration: gtk::Label,
|
||||
@ -82,7 +83,7 @@ pub struct PlayerTimes {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Duration(ClockTime);
|
||||
struct Duration(ClockTime);
|
||||
|
||||
impl Deref for Duration {
|
||||
type Target = ClockTime;
|
||||
@ -92,7 +93,7 @@ impl Deref for Duration {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Position(ClockTime);
|
||||
struct Position(ClockTime);
|
||||
|
||||
impl Deref for Position {
|
||||
type Target = ClockTime;
|
||||
@ -159,14 +160,19 @@ pub struct PlayerWidget {
|
||||
pub action_bar: gtk::ActionBar,
|
||||
player: gst_player::Player,
|
||||
controls: PlayerControls,
|
||||
pub timer: PlayerTimes,
|
||||
timer: PlayerTimes,
|
||||
info: PlayerInfo,
|
||||
rate: PlayerRate,
|
||||
}
|
||||
|
||||
impl Default for PlayerWidget {
|
||||
fn default() -> Self {
|
||||
let player = gst_player::Player::new(None, None);
|
||||
let dispatcher = gst_player::PlayerGMainContextSignalDispatcher::new(None);
|
||||
let player = gst_player::Player::new(
|
||||
None,
|
||||
// Use the gtk main thread
|
||||
Some(&dispatcher.upcast::<gst_player::PlayerSignalDispatcher>()),
|
||||
);
|
||||
|
||||
let mut config = player.get_config();
|
||||
config.set_user_agent(USER_AGENT);
|
||||
@ -250,40 +256,10 @@ impl PlayerWidget {
|
||||
w
|
||||
}
|
||||
|
||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||
fn init(s: &Rc<Self>, sender: &Sender<Action>) {
|
||||
Self::connect_control_buttons(s);
|
||||
Self::connect_rate_buttons(s);
|
||||
|
||||
// Log gst warnings.
|
||||
s.player.connect_warning(move |_, warn| warn!("gst warning: {}", warn));
|
||||
|
||||
// Log gst errors.
|
||||
s.player.connect_error(clone!(sender => move |_, error| {
|
||||
// FIXME: should never occur and should not be user facing.
|
||||
sender.send(Action::ErrorNotification(format!("Player Error: {}", error)))
|
||||
.map_err(|err| error!("Error: {}", err))
|
||||
.ok();
|
||||
|
||||
}));
|
||||
|
||||
s.player.connect_duration_changed(clone!(sender => move |_, clock| {
|
||||
sender.send(Action::PlayerDurationChanged(Duration(clock)))
|
||||
.map_err(|err| error!("Error: {}", err))
|
||||
.ok();
|
||||
}));
|
||||
|
||||
s.player.connect_position_updated(clone!(sender => move |_, clock| {
|
||||
sender.send(Action::PlayerPositionUpdated(Position(clock)))
|
||||
.map_err(|err| error!("Error: {}", err))
|
||||
.ok();
|
||||
}));
|
||||
|
||||
s.player.connect_end_of_stream(clone!(sender => move |player| {
|
||||
sender.send(Action::PlayerEndofStream(player.clone()))
|
||||
.map_err(|err| error!("Error: {}", err))
|
||||
.ok();
|
||||
}));
|
||||
Self::connect_gst_signals(s, sender);
|
||||
}
|
||||
|
||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||
@ -302,6 +278,37 @@ impl PlayerWidget {
|
||||
s.controls.forward.connect_clicked(clone!(s => move |_| s.fast_forward()));
|
||||
}
|
||||
|
||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||
fn connect_gst_signals(s: &Rc<Self>, sender: &Sender<Action>) {
|
||||
// Log gst warnings.
|
||||
s.player.connect_warning(move |_, warn| warn!("gst warning: {}", warn));
|
||||
|
||||
// Log gst errors.
|
||||
s.player.connect_error(clone!(sender => move |_, error| {
|
||||
// FIXME: should never occur and should not be user facing.
|
||||
sender.send(Action::ErrorNotification(format!("Player Error: {}", error)))
|
||||
.map_err(|err| error!("Error: {}", err))
|
||||
.ok();
|
||||
|
||||
}));
|
||||
|
||||
// The followign callbacks require `Send` but are handled by the gtk main loop
|
||||
let s2 = SendCell::new(s.clone());
|
||||
|
||||
// Update the duration label and the slider
|
||||
s.player.connect_duration_changed(clone!(s2 => move |_, clock| {
|
||||
s2.borrow().timer.on_duration_changed(Duration(clock));
|
||||
}));
|
||||
|
||||
// Update the position label and the slider
|
||||
s.player.connect_position_updated(clone!(s2 => move |_, clock| {
|
||||
s2.borrow().timer.on_position_updated(Position(clock));
|
||||
}));
|
||||
|
||||
// Reset the slider to 0 and show a play button
|
||||
s.player.connect_end_of_stream(clone!(s2 => move |_| s2.borrow().stop()));
|
||||
}
|
||||
|
||||
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||
fn connect_rate_buttons(s: &Rc<Self>) {
|
||||
s.rate.radio_normal.connect_toggled(clone!(s => move |_| s.on_rate_changed(1.00)));
|
||||
|
||||
Loading…
Reference in New Issue
Block a user