[gnome-subtitles] Fix bug #453469 - Slow and Fast Motion Option, based on a patch from Keith.
- From: Pedro Daniel da Rocha Melo e Castro <pcastro src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-subtitles] Fix bug #453469 - Slow and Fast Motion Option, based on a patch from Keith.
- Date: Sun, 8 May 2011 23:31:43 +0000 (UTC)
commit 6049c758a93db352b4cee76bb85170d77894f296
Author: Pedro Castro <mail pedrocastro org>
Date: Mon May 9 00:22:47 2011 +0100
Fix bug #453469 - Slow and Fast Motion Option, based on a patch from Keith.
src/External/GStreamerPlaybin/Engine.cs | 16 +++---
src/External/GStreamerPlaybin/main.c | 9 ++-
src/Glade/MainWindow.glade | 72 +++++++++++++++++++++++-
src/GnomeSubtitles/Core/EventHandlers.cs | 12 ++++
src/GnomeSubtitles/Ui/VideoPreview/Player.cs | 80 +++++++++++++++++++-------
src/GnomeSubtitles/Ui/VideoPreview/Video.cs | 22 +++++++
src/GnomeSubtitles/Ui/WidgetNames.cs | 3 +
7 files changed, 179 insertions(+), 35 deletions(-)
---
diff --git a/src/External/GStreamerPlaybin/Engine.cs b/src/External/GStreamerPlaybin/Engine.cs
index 94d289c..aecb197 100644
--- a/src/External/GStreamerPlaybin/Engine.cs
+++ b/src/External/GStreamerPlaybin/Engine.cs
@@ -1,6 +1,7 @@
/*
Copyright (C) 2007 Goran Sterjov, Pedro Castro
+ Copyright (C) 2011 Pedro Castro
This file is part of the GStreamer Playbin Wrapper.
Derived from Fuse.
@@ -38,7 +39,7 @@ namespace GStreamer
public delegate void ErrorEventHandler (ErrorEventArgs args);
public delegate void BufferEventHandler (BufferEventArgs args);
public delegate void EndOfStreamEventHandler ();
-
+
public delegate void StateEventHandler (StateEventArgs args);
public delegate void VideoInfoEventHandler (VideoInfoEventArgs args);
public delegate void TagEventHandler (TagEventArgs args);
@@ -212,25 +213,24 @@ namespace GStreamer
/// <summary>
/// Seeks to the nearest millisecond on the media file.
/// </summary>
- public void Seek (TimeSpan time)
+ public void Seek (TimeSpan time, float speed)
{
if (isUnloaded)
return;
- gst_binding_set_position (engine, (ulong) time.TotalMilliseconds);
+ gst_binding_set_position (engine, (ulong) time.TotalMilliseconds, speed);
}
/// <summary>
/// Seeks to the nearest millisecond on the media file.
/// </summary>
- public void Seek (double milliseconds)
+ public void Seek (double milliseconds, float speed)
{
TimeSpan time = TimeSpan.FromMilliseconds (milliseconds);
- Seek (time);
+ Seek (time, speed);
}
-
/// <summary>
/// Seeks to the specified track number.
/// </summary>
@@ -491,7 +491,7 @@ namespace GStreamer
[DllImport("gstreamer_playbin")]
static extern int gst_binding_get_volume (HandleRef play);
[DllImport("gstreamer_playbin")]
- static extern void gst_binding_set_position (HandleRef play, ulong pos);
+ static extern void gst_binding_set_position (HandleRef play, ulong pos, float speed);
[DllImport("gstreamer_playbin")]
static extern void gst_binding_set_track (HandleRef play, ulong track_number);
[DllImport("gstreamer_playbin")]
@@ -587,4 +587,4 @@ namespace GStreamer
}
-}
\ No newline at end of file
+}
diff --git a/src/External/GStreamerPlaybin/main.c b/src/External/GStreamerPlaybin/main.c
index 8d94fea..b71576a 100644
--- a/src/External/GStreamerPlaybin/main.c
+++ b/src/External/GStreamerPlaybin/main.c
@@ -1,6 +1,7 @@
/*
Copyright (C) 2007 Goran Sterjov, Pedro Castro
+ Copyright (C) 2011 Pedro Castro
This file is part of the GStreamer Playbin Wrapper.
Derived from Fuse.
@@ -341,20 +342,20 @@ guint64 gst_binding_get_position (gstPlay *play) {
}
// set the position of the media file
-void gst_binding_set_position (gstPlay *play, gint64 time_sec) {
+void gst_binding_set_position (gstPlay *play, gint64 time_sec, float speed) {
if (!isValid (play)) return;
- gst_element_seek (play->element, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
+ gst_element_seek (play->element, speed, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
GST_SEEK_TYPE_SET, time_sec * GST_MSECOND,
GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
}
// set the position of the media file
-void gst_binding_set_track (gstPlay *play, gint64 track_number) {
+void gst_binding_set_track (gstPlay *play, gint64 track_number, float speed) {
if (!isValid (play)) return;
- gst_element_seek (play->element, 1.0, gst_format_get_by_nick ("track"),
+ gst_element_seek (play->element, speed, gst_format_get_by_nick ("track"),
GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, track_number - 1,
GST_SEEK_TYPE_NONE, -1);
}
diff --git a/src/Glade/MainWindow.glade b/src/Glade/MainWindow.glade
index a9c457c..faf6be9 100644
--- a/src/Glade/MainWindow.glade
+++ b/src/Glade/MainWindow.glade
@@ -1653,6 +1653,76 @@
</packing>
</child>
<child>
+ <widget class="GtkHBox" id="speedHBox">
+ <property name="visible">True</property>
+ <child>
+ <widget class="GtkButton" id="videoSpeedDownButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <signal name="clicked" handler="OnVideoSpeedDown"/>
+ <accelerator key="minus" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+ <child>
+ <widget class="GtkImage" id="videoSpeedDownButtonImage">
+ <property name="visible">True</property>
+ <property name="stock">gtk-remove</property>
+ <property name="icon-size">1</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">0</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="videoSpeedButton">
+ <property name="label">1.0x</property>
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <property name="focus_on_click">False</property>
+ <signal name="clicked" handler="OnVideoSpeed"/>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
+ <widget class="GtkButton" id="videoSpeedUpButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="relief">none</property>
+ <signal name="clicked" handler="OnVideoSpeedUp"/>
+ <accelerator key="plus" signal="activate" modifiers="GDK_CONTROL_MASK"/>
+ <child>
+ <widget class="GtkImage" id="videoSpeedUpButtonImage">
+ <property name="visible">True</property>
+ <property name="stock">gtk-add</property>
+ <property name="icon-size">1</property>
+ </widget>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">2</property>
+ </packing>
+ </child>
+ </widget>
+ <packing>
+ <property name="expand">False</property>
+ <property name="fill">False</property>
+ <property name="position">1</property>
+ </packing>
+ </child>
+ <child>
<widget class="GtkHScale" id="videoSlider">
<property name="visible">True</property>
<property name="adjustment">0 0 100 0.5 10 10</property>
@@ -1660,7 +1730,7 @@
<property name="value_pos">bottom</property>
</widget>
<packing>
- <property name="position">1</property>
+ <property name="position">2</property>
</packing>
</child>
</widget>
diff --git a/src/GnomeSubtitles/Core/EventHandlers.cs b/src/GnomeSubtitles/Core/EventHandlers.cs
index d9dfb5f..0697bd8 100644
--- a/src/GnomeSubtitles/Core/EventHandlers.cs
+++ b/src/GnomeSubtitles/Core/EventHandlers.cs
@@ -250,6 +250,18 @@ public class EventHandlers {
Base.Ui.Video.Forward();
}
+ public void OnVideoSpeedUp (object o, EventArgs args) {
+ Base.Ui.Video.SpeedUp();
+ }
+
+ public void OnVideoSpeedDown (object o, EventArgs args) {
+ Base.Ui.Video.SpeedDown();
+ }
+
+ public void OnVideoSpeed (object o, EventArgs args) {
+ Base.Ui.Video.SpeedReset();
+ }
+
public void OnVideoSeekTo (object o, EventArgs args) {
Base.Dialogs.Get(typeof(VideoSeekToDialog)).Show();
}
diff --git a/src/GnomeSubtitles/Ui/VideoPreview/Player.cs b/src/GnomeSubtitles/Ui/VideoPreview/Player.cs
index 9a406ef..48a4512 100644
--- a/src/GnomeSubtitles/Ui/VideoPreview/Player.cs
+++ b/src/GnomeSubtitles/Ui/VideoPreview/Player.cs
@@ -30,6 +30,7 @@ public delegate void PlayerErrorEventHandler (Uri videoUri, Exception e);
public delegate void VideoDurationEventHandler (TimeSpan duration);
public class Player {
+
private AspectFrame frame = null;
private Socket socket = null;
private Playbin playbin = null;
@@ -37,9 +38,13 @@ public class Player {
private bool hasFoundDuration = false;
private Uri videoUri = null;
private VideoInfo videoInfo = null;
+ private float speed = 1;
/* Constants */
public const float DefaultAspectRatio = 1.67f;
+ public const float DefaultMinSpeed = 0.1f;
+ public const float DefaultSpeedStep = 0.1f;
+ public const float DefaultMaxSpeed = 2;
public Player (AspectFrame aspectFrame) {
this.frame = aspectFrame;
@@ -49,23 +54,6 @@ public class Player {
InitializePlaybin();
}
- private void InitializePlaybin () {
- playbin = new Playbin();
-
- if (!playbin.Initiate(socket.Id))
- throw new PlayerCouldNotInitiateEngineException();
-
- playbin.Error += OnPlaybinError;
- playbin.EndOfStream += OnPlaybinEndOfStream;
- playbin.StateChanged += OnPlaybinStateChanged;
- playbin.FoundVideoInfo += OnPlaybinFoundVideoInfo;
- playbin.FoundTag += OnPlaybinFoundTag;
- }
-
- private void InitializePositionWatcher () {
- position = new PlayerPositionWatcher(GetPosition);
- position.Changed += OnPositionWatcherChanged;
- }
/* Events */
public event PlayerErrorEventHandler Error;
@@ -112,6 +100,10 @@ public class Player {
public Uri VideoUri {
get { return videoUri; }
}
+
+ public float Speed {
+ get { return speed; }
+ }
/* Public methods */
@@ -130,6 +122,7 @@ public class Player {
videoUri = null;
hasFoundDuration = false;
videoInfo = null;
+ speed = 1;
}
public void Play () {
@@ -140,6 +133,27 @@ public class Player {
playbin.Pause();
}
+ public void SpeedUp () {
+ if (this.speed >= DefaultMaxSpeed)
+ return;
+
+ this.speed += DefaultSpeedStep;
+ ChangeSpeed(this.speed);
+ }
+
+ public void SpeedDown () {
+ if (this.speed <= DefaultMinSpeed)
+ return;
+
+ this.speed -= DefaultSpeedStep;
+ ChangeSpeed(this.speed);
+ }
+
+ public void SpeedReset () {
+ this.speed = 1;
+ ChangeSpeed(this.speed);
+ }
+
public void Rewind (TimeSpan dec) {
Seek(playbin.CurrentPosition - dec);
}
@@ -147,13 +161,13 @@ public class Player {
public void Forward (TimeSpan inc) {
Seek(playbin.CurrentPosition + inc);
}
-
+
public void Seek (TimeSpan newPosition) {
- playbin.Seek(newPosition);
+ playbin.Seek(newPosition, speed);
}
public void Seek (double newPosition) {
- playbin.Seek(newPosition); // newPosition in milliseconds
+ playbin.Seek(newPosition, speed); // newPosition in milliseconds
}
public void Dispose () {
@@ -174,12 +188,34 @@ public class Player {
socket.Show();
}
+ private void InitializePlaybin () {
+ playbin = new Playbin();
+
+ if (!playbin.Initiate(socket.Id))
+ throw new PlayerCouldNotInitiateEngineException();
+
+ playbin.Error += OnPlaybinError;
+ playbin.EndOfStream += OnPlaybinEndOfStream;
+ playbin.StateChanged += OnPlaybinStateChanged;
+ playbin.FoundVideoInfo += OnPlaybinFoundVideoInfo;
+ playbin.FoundTag += OnPlaybinFoundTag;
+ }
+
+ private void InitializePositionWatcher () {
+ position = new PlayerPositionWatcher(GetPosition);
+ position.Changed += OnPositionWatcherChanged;
+ }
+
/// <summary>Gets the current player position.</summary>
private TimeSpan GetPosition () {
return playbin.CurrentPosition;
}
-
+ private void ChangeSpeed (float newSpeed) {
+ playbin.Seek(playbin.CurrentPosition, newSpeed);
+ }
+
+
/* Event members */
private void OnPlaybinError (ErrorEventArgs args) {
@@ -236,4 +272,4 @@ public class Player {
}
-}
\ No newline at end of file
+}
diff --git a/src/GnomeSubtitles/Ui/VideoPreview/Video.cs b/src/GnomeSubtitles/Ui/VideoPreview/Video.cs
index 3a9d8a1..c1b4440 100644
--- a/src/GnomeSubtitles/Ui/VideoPreview/Video.cs
+++ b/src/GnomeSubtitles/Ui/VideoPreview/Video.cs
@@ -158,6 +158,21 @@ public class Video {
player.Forward(position.SeekIncrement);
}
+ public void SpeedUp () {
+ player.SpeedUp();
+ UpdateSpeedControls(player.Speed);
+ }
+
+ public void SpeedDown () {
+ player.SpeedDown();
+ UpdateSpeedControls(player.Speed);
+ }
+
+ public void SpeedReset () {
+ player.SpeedReset();
+ UpdateSpeedControls(player.Speed);
+ }
+
/// <summary>Seeks to the specified time.</summary>
/// <param name="time">The time position to seek to, in seconds.</param>
public void Seek (TimeSpan time) {
@@ -202,6 +217,13 @@ public class Video {
private void Pause () {
player.Pause();
}
+
+ private void UpdateSpeedControls (float speed) {
+ (Base.GetWidget(WidgetNames.VideoSpeedButton) as Button).Label = String.Format("{0:0.0}x", speed);
+
+ Base.GetWidget(WidgetNames.VideoSpeedDownButton).Sensitive = (speed > Player.DefaultMinSpeed);
+ Base.GetWidget(WidgetNames.VideoSpeedUpButton).Sensitive = (speed < Player.DefaultMaxSpeed);
+ }
private void SetCustomIcons () {
/* Set the icon for the SetSubtitleStart button */
diff --git a/src/GnomeSubtitles/Ui/WidgetNames.cs b/src/GnomeSubtitles/Ui/WidgetNames.cs
index bae661e..069b04d 100644
--- a/src/GnomeSubtitles/Ui/WidgetNames.cs
+++ b/src/GnomeSubtitles/Ui/WidgetNames.cs
@@ -126,6 +126,9 @@ public class WidgetNames {
public const string VideoPlaybackHBox = "videoPlaybackHBox";
public const string VideoSlider = "videoSlider";
public const string VideoPlayPauseButton = "videoPlayPauseButton";
+ public const string VideoSpeedButton = "videoSpeedButton";
+ public const string VideoSpeedUpButton = "videoSpeedUpButton";
+ public const string VideoSpeedDownButton = "videoSpeedDownButton";
/* Subtitle area */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]