aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjenkins4kodi <jenkins4kodi@users.noreply.github.com>2015-04-11 10:12:00 +0200
committerjenkins4kodi <jenkins4kodi@users.noreply.github.com>2015-04-11 10:12:00 +0200
commit7c04112418eaf26fec2220ad66cc081cefcc6c90 (patch)
tree22bde23a92885fceb20855b236d90fdf04294dfa
parent607500245bfa9c9b76187e23b017b28c3854afdf (diff)
parenta69dde35a0ee4652a302e5783117a901e4e21b97 (diff)
Merge pull request #6801 from xhaggi/builtin-seek-support
-rw-r--r--xbmc/interfaces/Builtins.cpp12
-rw-r--r--xbmc/interfaces/json-rpc/PlayerOperations.cpp22
-rw-r--r--xbmc/interfaces/json-rpc/schema/methods.json6
-rw-r--r--xbmc/interfaces/json-rpc/schema/version.txt2
-rw-r--r--xbmc/utils/SeekHandler.cpp56
-rw-r--r--xbmc/utils/SeekHandler.h4
6 files changed, 81 insertions, 21 deletions
diff --git a/xbmc/interfaces/Builtins.cpp b/xbmc/interfaces/Builtins.cpp
index ddb898326c..0e2644d900 100644
--- a/xbmc/interfaces/Builtins.cpp
+++ b/xbmc/interfaces/Builtins.cpp
@@ -22,6 +22,7 @@
#include "system.h"
#include "utils/AlarmClock.h"
#include "utils/Screenshot.h"
+#include "utils/SeekHandler.h"
#include "Application.h"
#include "ApplicationMessenger.h"
#include "Autorun.h"
@@ -150,6 +151,7 @@ const BUILT_IN commands[] = {
{ "NotifyAll", true, "Notify all connected clients" },
{ "Extract", true, "Extracts the specified archive" },
{ "PlayMedia", true, "Play the specified media file (or playlist)" },
+ { "Seek", true, "Performs a seek in seconds on the current playing media file" },
{ "ShowPicture", true, "Display a picture by file path" },
{ "SlideShow", true, "Run a slideshow from the specified directory" },
{ "RecursiveSlideShow", true, "Run a slideshow from the specified directory, including all subdirs" },
@@ -813,6 +815,16 @@ int CBuiltins::Execute(const std::string& execString)
}
}
}
+ else if (execute == "seek")
+ {
+ if (!params.size())
+ {
+ CLog::Log(LOGERROR, "Seek called with empty parameter");
+ return -3;
+ }
+ if (g_application.m_pPlayer->IsPlaying())
+ CSeekHandler::Get().SeekSeconds(atoi(params[0].c_str()));
+ }
else if (execute == "showpicture")
{
if (!params.size())
diff --git a/xbmc/interfaces/json-rpc/PlayerOperations.cpp b/xbmc/interfaces/json-rpc/PlayerOperations.cpp
index 80d885ea4d..cd8e751fdc 100644
--- a/xbmc/interfaces/json-rpc/PlayerOperations.cpp
+++ b/xbmc/interfaces/json-rpc/PlayerOperations.cpp
@@ -47,6 +47,7 @@
#include "cores/playercorefactory/PlayerCoreConfig.h"
#include "cores/playercorefactory/PlayerCoreFactory.h"
#include "settings/MediaSettings.h"
+#include "utils/SeekHandler.h"
using namespace JSONRPC;
using namespace PLAYLIST;
@@ -392,16 +393,18 @@ JSONRPC_STATUS CPlayerOperations::Seek(const std::string &method, ITransportLaye
{
case Video:
case Audio:
+ {
if (!g_application.m_pPlayer->CanSeek())
return FailedToExecute;
-
- if (parameterObject["value"].isObject())
- g_application.SeekTime(ParseTimeInSeconds(parameterObject["value"]));
- else if (IsType(parameterObject["value"], NumberValue))
- g_application.SeekPercentage(parameterObject["value"].asFloat());
- else if (parameterObject["value"].isString())
+
+ const CVariant& value = parameterObject["value"];
+ if (IsType(value, NumberValue) ||
+ (value.isObject() && value.isMember("percentage")))
+ g_application.SeekPercentage(IsType(value, NumberValue) ? value.asFloat() : value["percentage"].asFloat());
+ else if (value.isString() ||
+ (value.isObject() && value.isMember("step")))
{
- std::string step = parameterObject["value"].asString();
+ std::string step = value.isString() ? value.asString() : value["step"].asString();
if (step == "smallforward")
CBuiltins::Execute("playercontrol(smallskipforward)");
else if (step == "smallbackward")
@@ -413,6 +416,10 @@ JSONRPC_STATUS CPlayerOperations::Seek(const std::string &method, ITransportLaye
else
return InvalidParams;
}
+ else if (value.isObject() && value.isMember("seconds") && value.size() == 1)
+ CSeekHandler::Get().SeekSeconds(static_cast<int>(value["seconds"].asInteger()));
+ else if (value.isObject())
+ g_application.SeekTime(ParseTimeInSeconds(value.isMember("time") ? value["time"] : value));
else
return InvalidParams;
@@ -420,6 +427,7 @@ JSONRPC_STATUS CPlayerOperations::Seek(const std::string &method, ITransportLaye
GetPropertyValue(player, "time", result["time"]);
GetPropertyValue(player, "totaltime", result["totaltime"]);
return OK;
+ }
case Picture:
case None:
diff --git a/xbmc/interfaces/json-rpc/schema/methods.json b/xbmc/interfaces/json-rpc/schema/methods.json
index 1b82ee2203..7b2ede3eac 100644
--- a/xbmc/interfaces/json-rpc/schema/methods.json
+++ b/xbmc/interfaces/json-rpc/schema/methods.json
@@ -291,7 +291,11 @@
{ "name": "value", "required": true, "type": [
{ "$ref": "Player.Position.Percentage", "required": true, "description": "Percentage value to seek to" },
{ "$ref": "Player.Position.Time", "required": true, "description": "Time to seek to" },
- { "type": "string", "enum": [ "smallforward", "smallbackward", "bigforward", "bigbackward" ], "required": true, "description": "Seek by predefined jumps" }
+ { "type": "string", "enum": [ "smallforward", "smallbackward", "bigforward", "bigbackward" ], "required": true, "description": "Seek by predefined jumps" },
+ { "type": "object", "properties": { "percentage": { "$ref": "Player.Position.Percentage", "required": true, "description": "Percentage value to seek to" } }, "additionalProperties": false, "required": true },
+ { "type": "object", "properties": { "time": { "$ref": "Player.Position.Time", "required": true, "description": "Time to seek to" } }, "additionalProperties": false, "required": true },
+ { "type": "object", "properties": { "step": { "type": "string", "enum": [ "smallforward", "smallbackward", "bigforward", "bigbackward" ], "required": true, "description": "Seek by predefined jumps" } }, "additionalProperties": false, "required": true },
+ { "type": "object", "properties": { "seconds": { "type": "integer", "required": true, "description": "Seek by the given number of seconds" } }, "additionalProperties": false, "required": true }
]
}
],
diff --git a/xbmc/interfaces/json-rpc/schema/version.txt b/xbmc/interfaces/json-rpc/schema/version.txt
index 2496b04b84..961b1c8ecf 100644
--- a/xbmc/interfaces/json-rpc/schema/version.txt
+++ b/xbmc/interfaces/json-rpc/schema/version.txt
@@ -1 +1 @@
-6.24.0
+6.25.0
diff --git a/xbmc/utils/SeekHandler.cpp b/xbmc/utils/SeekHandler.cpp
index ad34e2060a..dbc4d933c6 100644
--- a/xbmc/utils/SeekHandler.cpp
+++ b/xbmc/utils/SeekHandler.cpp
@@ -110,7 +110,7 @@ int CSeekHandler::GetSeekSeconds(bool forward, SeekType type)
int seconds = 0;
// when exceeding the selected amount of steps repeat/sum up the last step size
- if ((size_t)abs(m_seekStep) <= seekSteps.size())
+ if (static_cast<size_t>(abs(m_seekStep)) <= seekSteps.size())
seconds = seekSteps.at(abs(m_seekStep) - 1);
else
seconds = seekSteps.back() * (abs(m_seekStep) - seekSteps.size() + 1);
@@ -120,13 +120,17 @@ int CSeekHandler::GetSeekSeconds(bool forward, SeekType type)
void CSeekHandler::Seek(bool forward, float amount, float duration /* = 0 */, bool analogSeek /* = false */, SeekType type /* = SEEK_TYPE_VIDEO */)
{
+ // abort if we do not have a play time or already perform a seek
+ if (g_infoManager.GetTotalPlayTime() == 0 ||
+ g_infoManager.m_performingSeek)
+ return;
+
+ CSingleLock lock(m_critSection);
+
// not yet seeking
if (!m_requireSeek)
{
- if (g_infoManager.GetTotalPlayTime())
- m_percent = (float)g_infoManager.GetPlayTime() / g_infoManager.GetTotalPlayTime() * 0.1f;
- else
- m_percent = 0.0f;
+ m_percent = static_cast<float>(g_infoManager.GetPlayTime()) / g_infoManager.GetTotalPlayTime() * 0.1f;
m_percentPlayTime = m_percent;
// tell info manager that we have started a seek operation
@@ -159,10 +163,7 @@ void CSeekHandler::Seek(bool forward, float amount, float duration /* = 0 */, bo
int seekSeconds = GetSeekSeconds(forward, type);
if (seekSeconds != 0)
{
- float percentPerSecond = 0.0f;
- if (g_infoManager.GetTotalPlayTime())
- percentPerSecond = 100.0f / (float)g_infoManager.GetTotalPlayTime();
-
+ float percentPerSecond = 100.0f / static_cast<float>(g_infoManager.GetTotalPlayTime());
m_percent = m_percentPlayTime + percentPerSecond * seekSeconds;
g_infoManager.SetSeekStepSize(seekSeconds);
@@ -175,13 +176,44 @@ void CSeekHandler::Seek(bool forward, float amount, float duration /* = 0 */, bo
}
}
- if (m_percent > 100.0f) m_percent = 100.0f;
- if (m_percent < 0.0f) m_percent = 0.0f;
+ if (m_percent > 100.0f)
+ m_percent = 100.0f;
+ if (m_percent < 0.0f)
+ m_percent = 0.0f;
}
m_timer.StartZero();
}
+void CSeekHandler::SeekSeconds(int seconds)
+{
+ // abort if we do not have a play time or already perform a seek
+ if (seconds == 0 ||
+ g_infoManager.GetTotalPlayTime() == 0 ||
+ g_infoManager.m_performingSeek)
+ return;
+
+ CSingleLock lock(m_critSection);
+
+ m_requireSeek = true;
+ m_seekDelay = 0;
+
+ g_infoManager.SetSeeking(true);
+ g_infoManager.SetSeekStepSize(seconds);
+
+ float percentPlayTime = static_cast<float>(g_infoManager.GetPlayTime()) / g_infoManager.GetTotalPlayTime() * 0.1f;
+ float percentPerSecond = 100.0f / static_cast<float>(g_infoManager.GetTotalPlayTime());
+
+ m_percent = percentPlayTime + percentPerSecond * seconds;
+
+ if (m_percent > 100.0f)
+ m_percent = 100.0f;
+ if (m_percent < 0.0f)
+ m_percent = 0.0f;
+
+ m_timer.StartZero();
+}
+
float CSeekHandler::GetPercent() const
{
return m_percent;
@@ -194,7 +226,7 @@ bool CSeekHandler::InProgress() const
void CSeekHandler::Process()
{
- if (m_timer.GetElapsedMilliseconds() > m_seekDelay && m_requireSeek)
+ if (m_timer.GetElapsedMilliseconds() >= m_seekDelay && m_requireSeek)
{
g_infoManager.m_performingSeek = true;
diff --git a/xbmc/utils/SeekHandler.h b/xbmc/utils/SeekHandler.h
index e9809651d3..7782bb05fd 100644
--- a/xbmc/utils/SeekHandler.h
+++ b/xbmc/utils/SeekHandler.h
@@ -24,6 +24,7 @@
#include "interfaces/IActionListener.h"
#include "settings/Settings.h"
#include "settings/lib/ISettingCallback.h"
+#include "threads/CriticalSection.h"
#include "utils/Stopwatch.h"
enum SeekType
@@ -43,6 +44,7 @@ public:
virtual bool OnAction(const CAction &action);
void Seek(bool forward, float amount, float duration = 0, bool analogSeek = false, SeekType type = SEEK_TYPE_VIDEO);
+ void SeekSeconds(int seconds);
void Process();
void Reset();
@@ -69,4 +71,6 @@ private:
std::map<SeekType, std::vector<int> > m_forwardSeekSteps;
std::map<SeekType, std::vector<int> > m_backwardSeekSteps;
CStopWatch m_timer;
+
+ CCriticalSection m_critSection;
};