Skip to content

Instantly share code, notes, and snippets.

@aberba
Forked from Philip-Scott/VideoPlayer.vala
Created May 14, 2017 20:56
Show Gist options
  • Save aberba/9c93f1bbaef6ace59570f358fba3f308 to your computer and use it in GitHub Desktop.
Save aberba/9c93f1bbaef6ace59570f358fba3f308 to your computer and use it in GitHub Desktop.
ClutterGStreamer & Gtk video player widget in Vala
/*-
* Copyright (c) 2017
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Authored by: Felipe Escoto <felescoto95@hotmail.com>
*
*/
/*
Compile: valac --pkg gtk+-3.0 --pkg clutter-1.0 --pkg clutter-gst-3.0 --pkg clutter-gtk-1.0 VideoPlayer.vala
Usage: ./VideoPlayer file:///path/to/file.mp4
*/
public class Granite.Widgets.VideoPlayer : Gtk.EventBox {
public static void main (string[] args) {
Gtk.init (ref args);
Gst.init (ref args);
var err = GtkClutter.init (ref args);
if (err != Clutter.InitError.SUCCESS) {
error ("Could not initalize clutter: %s ", err.to_string ());
}
Gtk.Settings.get_default ().gtk_application_prefer_dark_theme = true;
var window = new Gtk.Window ();
var player = new Granite.Widgets.VideoPlayer ();
window.add (player);
window.show_all ();
player.video_uri = args[1];
player.playing = true;
Gtk.main ();
}
protected Clutter.Stage stage { get; private set; }
protected Clutter.Actor video_actor { get; private set; }
protected ClutterGst.Playback playback { get; private set; }
protected GtkClutter.Embed clutter;
private string video_uri_;
public string? video_uri {
get {
return video_uri_;
}
set {
stdout.printf ("Opening %s\n", value);
if (value == null) {
playback.uri = "";
} else {
playback.uri = value;
}
}
}
public bool playing {
get {
return playback.playing;
}
set {
stdout.printf ("playing: %s\n", value.to_string ());
if (playback.playing == value) {
return;
}
playback.playing = value;
}
}
construct {
events |= Gdk.EventMask.POINTER_MOTION_MASK;
events |= Gdk.EventMask.KEY_PRESS_MASK;
events |= Gdk.EventMask.KEY_RELEASE_MASK;
playback = new ClutterGst.Playback ();
playback.set_seek_flags (ClutterGst.SeekFlags.ACCURATE);
clutter = new GtkClutter.Embed ();
stage = (Clutter.Stage) clutter.get_stage ();
stage.background_color = {0, 0, 0, 0};
video_actor = new Clutter.Actor ();
#if VALA_0_34
var aspect_ratio = new ClutterGst.Aspectratio ();
#else
var aspect_ratio = ClutterGst.Aspectratio.@new ();
#endif
((ClutterGst.Aspectratio) aspect_ratio).paint_borders = false;
((ClutterGst.Content) aspect_ratio).player = playback;
video_actor.content = aspect_ratio;
video_actor.add_constraint (new Clutter.BindConstraint (stage, Clutter.BindCoordinate.WIDTH, 0));
video_actor.add_constraint (new Clutter.BindConstraint (stage, Clutter.BindCoordinate.HEIGHT, 0));
button_press_event.connect ((event) => {
// right click play/pause
if (event.button == Gdk.BUTTON_SECONDARY) {
playing = !playing;
}
return base.button_press_event(event);
});
stage.add_child (video_actor);
add (clutter);
show_all ();
}
public double get_progress () {
return playback.progress;
}
public void seek_jump_seconds (int seconds) {
var duration = playback.duration;
var progress = playback.progress;
var new_progress = ((duration * progress) + (double) seconds) / duration;
playback.progress = double.min (new_progress, 1.0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment