Add script offset / delay to Handy support. (#1573)

* Add script offset / delay to Handy support.

Further work on  #1376.

Offsets are added to the current video position, so a positive value leads to earlier motion.  (The most common setting.)

This is needed because most script times have a consistent delay when compared to the video. (Delay from the API calls to the server should be handled by the server offset calculation.)

* Rename scriptOffset to funscriptOffset
* Correct localisation keys

Co-authored-by: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
This commit is contained in:
UnluckyChemical765 2021-08-25 18:50:02 -07:00 committed by GitHub
parent 50217f6318
commit 45a9aabdaf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 76 additions and 16 deletions

View File

@ -56,6 +56,7 @@ fragment ConfigInterfaceData on ConfigInterfaceResult {
language
slideshowDelay
handyKey
funscriptOffset
}
fragment ConfigDLNAData on ConfigDLNAResult {

View File

@ -200,6 +200,8 @@ input ConfigInterfaceInput {
slideshowDelay: Int
"""Handy Connection Key"""
handyKey: String
"""Funscript Time Offset"""
funscriptOffset: Int
}
type ConfigInterfaceResult {
@ -226,6 +228,8 @@ type ConfigInterfaceResult {
slideshowDelay: Int
"""Handy Connection Key"""
handyKey: String
"""Funscript Time Offset"""
funscriptOffset: Int
}
input ConfigDLNAInput {

View File

@ -260,6 +260,10 @@ func (r *mutationResolver) ConfigureInterface(ctx context.Context, input models.
c.Set(config.HandyKey, *input.HandyKey)
}
if input.FunscriptOffset != nil {
c.Set(config.FunscriptOffset, *input.FunscriptOffset)
}
if err := c.Write(); err != nil {
return makeConfigInterfaceResult(), err
}

View File

@ -109,6 +109,7 @@ func makeConfigInterfaceResult() *models.ConfigInterfaceResult {
language := config.GetLanguage()
slideshowDelay := config.GetSlideshowDelay()
handyKey := config.GetHandyKey()
scriptOffset := config.GetFunscriptOffset()
return &models.ConfigInterfaceResult{
MenuItems: menuItems,
@ -123,6 +124,7 @@ func makeConfigInterfaceResult() *models.ConfigInterfaceResult {
Language: &language,
SlideshowDelay: &slideshowDelay,
HandyKey: &handyKey,
FunscriptOffset: &scriptOffset,
}
}

View File

@ -132,6 +132,7 @@ const CSSEnabled = "cssEnabled"
const WallPlayback = "wall_playback"
const SlideshowDelay = "slideshow_delay"
const HandyKey = "handy_key"
const FunscriptOffset = "funscript_offset"
// DLNA options
const DLNAServerName = "dlna.server_name"
@ -798,6 +799,11 @@ func (i *Instance) GetHandyKey() string {
return viper.GetString(HandyKey)
}
func (i *Instance) GetFunscriptOffset() int {
viper.SetDefault(FunscriptOffset, 0)
return viper.GetInt(FunscriptOffset)
}
// GetDLNAServerName returns the visible name of the DLNA server. If empty,
// "stash" will be used.
func (i *Instance) GetDLNAServerName() string {

View File

@ -1,4 +1,5 @@
### ✨ New Features
* Support setting a fixed funscript offset/delay. ([#1573](https://github.com/stashapp/stash/pull/1573))
* Added sort by options for image and gallery count for performers. ([#1671](https://github.com/stashapp/stash/pull/1671))
* Added sort by options for date, duration and rating for movies. ([#1663](https://github.com/stashapp/stash/pull/1663))
* Allow saving query page zoom level in saved and default filters. ([#1636](https://github.com/stashapp/stash/pull/1636))
@ -12,7 +13,7 @@
### 🎨 Improvements
* Move Play Selected Scenes, and Add/Remove Gallery Image buttons to button toolbar. ([#1673](https://github.com/stashapp/stash/pull/1673))
* Add image and gallery counts to tag list view. ([#1672](https://github.com/stashapp/stash/pull/1672))
* Added image and gallery counts to tag list view. ([#1672](https://github.com/stashapp/stash/pull/1672))
* Prompt when leaving gallery and image edit pages with unsaved changes. ([#1654](https://github.com/stashapp/stash/pull/1654), [#1669](https://github.com/stashapp/stash/pull/1669))
* Show largest duplicates first in scene duplicate checker. ([#1639](https://github.com/stashapp/stash/pull/1639))
* Added checkboxes to scene list view. ([#1642](https://github.com/stashapp/stash/pull/1642))

View File

@ -54,7 +54,10 @@ export class ScenePlayerImpl extends React.Component<
this.state = {
scrubberPosition: 0,
config: this.makeJWPlayerConfig(props.scene),
interactiveClient: new Interactive(this.props.config?.handyKey || ""),
interactiveClient: new Interactive(
this.props.config?.handyKey || "",
this.props.config?.funscriptOffset || 0
),
};
// Default back to Direct Streaming

View File

@ -37,6 +37,7 @@ export const SettingsInterfacePanel: React.FC = () => {
const [cssEnabled, setCSSEnabled] = useState<boolean>(false);
const [language, setLanguage] = useState<string>("en");
const [handyKey, setHandyKey] = useState<string>();
const [funscriptOffset, setFunscriptOffset] = useState<number>(0);
const [updateInterfaceConfig] = useConfigureInterface({
menuItems: menuItemIds,
@ -51,6 +52,7 @@ export const SettingsInterfacePanel: React.FC = () => {
language,
slideshowDelay,
handyKey,
funscriptOffset,
});
useEffect(() => {
@ -67,6 +69,7 @@ export const SettingsInterfacePanel: React.FC = () => {
setLanguage(iCfg?.language ?? "en-US");
setSlideshowDelay(iCfg?.slideshowDelay ?? 5000);
setHandyKey(iCfg?.handyKey ?? "");
setFunscriptOffset(iCfg?.funscriptOffset ?? 0);
}, [config]);
async function onSave() {
@ -281,7 +284,9 @@ export const SettingsInterfacePanel: React.FC = () => {
</Form.Group>
<Form.Group>
<h5>{intl.formatMessage({ id: "config.ui.handy_connection_key" })}</h5>
<h5>
{intl.formatMessage({ id: "config.ui.handy_connection_key.heading" })}
</h5>
<Form.Control
className="col col-sm-6 text-input"
value={handyKey}
@ -290,7 +295,25 @@ export const SettingsInterfacePanel: React.FC = () => {
}}
/>
<Form.Text className="text-muted">
{intl.formatMessage({ id: "config.ui.handy_connection_key_desc" })}
{intl.formatMessage({
id: "config.ui.handy_connection_key.description",
})}
</Form.Text>
</Form.Group>
<Form.Group>
<h5>
{intl.formatMessage({ id: "config.ui.funscript_offset.heading" })}
</h5>
<Form.Control
className="col col-sm-6 text-input"
type="number"
value={funscriptOffset}
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
setFunscriptOffset(Number.parseInt(e.currentTarget.value, 10));
}}
/>
<Form.Text className="text-muted">
{intl.formatMessage({ id: "config.ui.funscript_offset.description" })}
</Form.Text>
</Form.Group>

View File

@ -308,8 +308,10 @@
"heading": "Benutzerdefinierte CSS",
"option_label": "Benutzerdefiniertes CSS aktiviert"
},
"handy_connection_key": "Handy Verbindungsschlüssel",
"handy_connection_key_desc": "Handy Verbindungsschlüssel für interaktive Szenen.",
"handy_connection_key": {
"description": "Handy Verbindungsschlüssel für interaktive Szenen.",
"heading": "Handy Verbindungsschlüssel"
},
"language": {
"heading": "Sprache"
},

View File

@ -315,8 +315,14 @@
"heading": "Custom CSS",
"option_label": "Custom CSS enabled"
},
"handy_connection_key": "Handy Connection Key",
"handy_connection_key_desc": "Handy connection key to use for interactive scenes.",
"handy_connection_key": {
"description": "Handy connection key to use for interactive scenes.",
"heading": "Handy Connection Key"
},
"funscript_offset": {
"description": "Time offset in milliseconds for interactive scripts playback.",
"heading": "Funscript Offset (ms)"
},
"language": {
"heading": "Language"
},

View File

@ -308,8 +308,10 @@
"heading": "CSS customizado",
"option_label": "CSS customizado habilitado"
},
"handy_connection_key": "Chave de conexão",
"handy_connection_key_desc": "Chave de conexão para usar em cenas interativas.",
"handy_connection_key": {
"description": "Chave de conexão para usar em cenas interativas.",
"heading": "Chave de conexão"
},
"language": {
"heading": "Idioma"
},

View File

@ -308,8 +308,10 @@
"heading": "自定义样式",
"option_label": "自定义样式已启用"
},
"handy_connection_key": "快速连接密钥",
"handy_connection_key_desc": "用于互动场景的快速连接密钥",
"handy_connection_key": {
"description": "用于互动场景的快速连接密钥",
"heading": "快速连接密钥"
},
"language": {
"heading": "语言"
},

View File

@ -310,8 +310,10 @@
"heading": "自定義 CSS",
"option_label": "啟用自定義 CSS"
},
"handy_connection_key": "Handy 連線金鑰",
"handy_connection_key_desc": "播放支援互動性的短片時所用的 Handy 連線金鑰。",
"handy_connection_key": {
"description": "播放支援互動性的短片時所用的 Handy 連線金鑰。",
"heading": "Handy 連線金鑰"
},
"language": {
"heading": "語言"
},

View File

@ -26,11 +26,13 @@ function convertFunscriptToCSV(funscript: IFunscript) {
export class Interactive {
private _connected: boolean;
private _playing: boolean;
private _scriptOffset: number;
private _handy: Handy;
constructor(handyKey: string) {
constructor(handyKey: string, scriptOffset: number) {
this._handy = new Handy();
this._handy.connectionKey = handyKey;
this._scriptOffset = scriptOffset;
this._connected = false;
this._playing = false;
}
@ -76,7 +78,7 @@ export class Interactive {
return;
}
this._playing = await this._handy
.syncPlay(true, Math.round(position * 1000))
.syncPlay(true, Math.round(position * 1000 + this._scriptOffset))
.then(() => true);
}