Lovense Pattern Editor
Lovense Pattern Editor is a set of SDK tools for web-based audio/video platforms. Integration will allow you to:
- Make your audio/video interactive by enabling users to sync their Lovense toys to on-screen action or audio.
- Support FunScript, Lovense Patterns, and Lovense AI Sync (allowing toy vibrations match on-screen movement in real-time).
Both Lovense Remote and VibeMate supports sync to audio/video. Choose an app before integrating.
APPs | Pros | Cons |
---|---|---|
Lovense Remote is an app for Lovense users to control their toys. It is the essential app for Lovense users. | Lovense toy users most likely already have installed Lovense Remote. | 1. Users need to play audio/video in a separate browser and connect their toy via Lovense Remote mobile. 2. Only supports sync to video/audio which has scripts. |
VibeMate is a new browser app for viewers to watch livestream shows and videos. | 1. A single browser app that supports both connecting toys and accessing your website. 2. Supports syncing to video/audio which has scripts, as well as Lovense AI Sync. Lovense AI Sync lets viewers sync to on-screen action in real-time, offering an truly immersive user experience. VibeMate prioritizes manual scripts; if none are found, it will use AI. 3. Supports pattern creation, without you needing to further integrate. | Users need to download VibeMate separately. |
Configure the Developer Dashboard
Go to the developer dashboard and get your developer token.
⚠️Note: Your website name will be displayed to users. Please enter it carefully.
Integrate SDK
Step 1: Get ctoken
See here
Step 2: Initialization
Integrate pattern-sdk.js
into your website.
<script src="https://cdn.lovense-api.com/peditor-v2/pattern-sdk.js"></script>
Initialize the SDK.
Note: Call this method every time you open a media page or switch media.
const lovensePattern = new LovensePattern()
Sync with Lovense Toys
Quick Integration Method (Recommended for Most Cases)
This is a simplified method for syncing to Lovense toys. It supports almost all websites, including MPA and SPA, and almost all possible situations:
- You can call it for creating connection with Lovense Remote or VibeMate. For example, on a list page.
- You must call it every time you open a media page or switch media.
Note: Click here to check the demo page, you will be able to see the real case code. If you need more control over the syncing process, see the Advanced Custom Sync Methods section below.
Parameters | Description | Type | Required |
---|---|---|---|
ctoken | See here | string | Yes |
mediaId | The media's ID from your platform. | string | Yes |
duration | The media's total duration (in ms) | number | Yes |
videoEl | The <video> DOM element. Make sure that VideoEl is detected on the video/audio playback page when you call this method. Only after detection can the toy sync with video/audio. | object | No |
patternLink | Supports patterns from funScript and Lovense (patterns created in Lovense software). A pattern file's URL. | string | No |
patternData | The pattern data. | array | No |
btnId | The Sync Button will be displayed in this btnId. You can create a div, the btnId will be the Id of this div. | string | Yes |
syncButtonText | The default text on the button is "Sync with Lovense toy". When users click it, they will be prompted to connect to Lovense Remote. Then they can sync to video/audio. | string | No |
syncedButtonText | The default text is "Synced with Lovense toy". Users can click it to disconnect from Lovense Remote. | string | No |
isVR | This is for VR videos, this parameter is passed to display the short code pop-ups. | boolean | No |
supportedApp | 1: only allow syncing via Lovense Remote app. 2: only allow syncing with VibeMate app. 3: support both Lovense Remote and VibeMate | number | yes |
lovensePattern.sync({
ctoken: "[ctoken]",
mediaId: "[mediaId]",
// or videoId: "[mediaId]"
duration: "[duration]",
videoEl: document.querySelector("video"),
patternLink: "[pattern link]"// The funcript file download link
patternData: [
{ pos: 50, at: 1000 },
{ pos: 80, at: 2000 },
{ pos: 20, at: 3000 },
], // FunScript data
btnId: "[btnId]",
supportedApp: 3
})
lovensePattern.sync({
ctoken: "[ctoken]",
mediaId: "[mediaId]",
// or videoId: "[mediaId]"
duration: "[duration]",
videoEl: document.querySelector("video"),
patternLink: "[pattern link]"// The Lovense pattern file download link
patternData: [
{ v: 10, t: 1000 },
{ v: 20, t: 2000 },
{ v: 5, t: 3000 },
], // Lovense Pattern data
btnId: "[btnId]",
supportedApp: 3
})
Now, you've finished integrating Sync with Lovense toys. When you play a video/audio, your toys will sync to the action in it. Click here to see how it will work on your website. For the button and pop-ups which will display on your website, click here to change their layout if desired.
Advanced Custom Sync Methods
If you need more control over the syncing process, you can use the following advanced methods instead of the simplified sync()
method. These methods allow you to customize every aspect of the connection and syncing logic.
Note: Click here to check the demo page, you will be able to see the real case code.
Workflow
Step 1: Advanced Initialization
lovensePattern.init
Note: Call this method every time you open a media page or switch media.
Parameters | Description | Type | Required |
---|---|---|---|
ctoken | See here | string | Yes |
mediaId | The media's ID from your platform.videoId can also be used here. | string | Yes |
duration | The media's total duration (in ms) | number | Yes |
videoEl | The <video> DOM element. Please make sure that VideoEl is detected on the video/audio playback page, when you calling this method. Only after detection, the toy can sync with the video/audio. | object | No |
const lovensePattern = new LovensePattern()
lovensePattern.init({
ctoken: "[ctoken]",
mediaId: "[mediaId]",
// or videoId: "[mediaId]"
videoEl: document.querySelector("video"),
// or videoEl: "document.querySelector("audio")"
duration: "[duration]",
})
Step 2: Connect to Apps
We support syncing to audio/video with Lovense Remote or VibeMate.
Connect to Lovense Remote (optional)
Get a QR Code, app URL, or Unique Code to connect to Lovense Remote. Supports connecting to Lovense Remote from both PC and mobile-based websites.
Note: If your user has already connected Lovense Remote to your platform, you don't need to call this method again when they switch to a new media. Connection persistence is supported. If you call this method again, a new QR code will be shown.
callback | Description | Type |
---|---|---|
qrCode | Suggested to display it for PC browser users. | string |
appOpenUrl | Suggested to display it for mobile browser users. | string |
code | It's a 6 digit code for use in connecting to VR videos. | string |
lovensePattern.getApp((data) => {
console.log(data) // { qrCode: "[qrCode]", appOpenUrl: "[appOpenUrl]", code: "[Unique code]" }
// If your user is on a PC, show the QR Code and have them scan it with Lovense Remote mobile app; If your user is on mobile, display a button{appOpenUrl} which can connect to the Lovense Remote app. If your user is on a VR headset, show the Unique Code and have them enter it with Lovense Remote mobile app.
})
Connect to VibeMate (optional)
Get a unique VibeMate download URL for each of your website pages. When your user downloads/opens VibeMate through this URL they will land back on that page.
Note: If your user has already connected VibeMate to your platform, you don't need to call this method again when they switch to a new media. Connection persistence is supported. If you call this method again, a new QR code will be shown.
callback | Description | Type |
---|---|---|
qrCode | Suggested to display it for PC browser users. | string |
url | The unique VibeMate download URL of each of your website pages. | string |
result | Connection state | boolean |
vibemate.getApp((data) => {
console.log(data) // { url: "[url]", result: true/false }
// If your user is on VibeMate, it will return { result: true }. In this case, please remove the syncing buttons from the video page. VibeMate will display the syncing functionality from our side.
// If your user is on other browsers, it will return { result: false, url: [url] }. When the user downloads/opens VibeMate through this URL, they will land back on this page directly.
})
Once VibeMate/Lovense Remote is connected, the event appConnected
will be triggered. Then you should display the connection status on your website, or update the status of your connection button.
lovensePattern.on("appConnected", () => {
console.log("appConnected")
// Once Lovense Remote or VibeMate is connected, your platform can control the toys.
})
Step 3: Load pattern(s)
If you are using FunScript, this step is required every time your user connects the Lovense Remote/VibeMate app to your platform, even when the audio/video is already playing.
Note: If your user syncs with VibeMate, then VibeMate will react to scripts first. If there are no scripts, it will switch to AI Sync automatically.
lovensePattern.loadPattern
Call this method when you want to control all connected toys with one pattern.
Parameters | Description | Type | Required |
---|---|---|---|
type | Pattern's type, supports patterns from funScript and lovense (patterns created in Lovense software) | string | No |
data | A pattern's data. | array | No |
patternLink | Pattern file's URL | string | No |
lovensePattern.loadPattern({
type: "funScript",
patternLink: "[pattern link]"// The funscript file download link
data: [
{ pos: 50, at: 1000 },
{ pos: 80, at: 2000 },
{ pos: 20, at: 3000 },
], // FunScript data
})// If data is not null, the pattern from data will be used. If data is null, the pattern from patternLink will be used. If both are null, an error will be returned.
lovensePattern.loadMultiplePatterns
Call this method when you want to control connected toys separately with different patterns. An 'appToyStatus' event will be triggered, which includes the toy IDs of all connected toys returned when connecting to Lovense Remote.
TIP
This method is available in Lovense Remote version v7.63.0
or later.
Parameters | Description | Type | Required |
---|---|---|---|
type | Pattern's type, supports patterns from funScript and lovense (patterns created in Lovense software) | string | No |
data | A pattern's data. | array | No |
patternLink | Pattern file's URL | string | No |
toyId | Toy ID | string | No |
// Connected toys: Lush 4, Nora, Domi 2.
lovensePattern.loadMultiplePatterns(
[
{
type: 'funScript',
patternLink: '[pattern link]',
toyId: '[Lush 4 toyId]',
},
{
type: 'funScript',
patternLink: '[pattern link]',
toyId: '[Nora toyId]',
},
{
type: 'funScript',
patternLink: '[pattern link]',
data: [
{ pos: 50, at: 1000 },
{ pos: 80, at: 2000 },
{ pos: 20, at: 3000 },
],// If data is not null, the pattern from data will be used. If data is null, the pattern from patternLink will be used. If both are null, an error will be returned.
toyId: '[Domi 2 toyId]',
}
])
// Lush 4 reacts to the first patternLink; Nora reacts to the second patternLink; Domi 2 reacts to the third pattern data.
// Connected toys: Lush 4, Nora, Domi 2.
lovensePattern.loadMultiplePatterns([
{
type: 'funScript',
patternLink: '[pattern link]',
},
{
type: 'funScript',
patternLink: '[pattern link]',
data: [
{ pos: 50, at: 1000 },
{ pos: 80, at: 2000 },
{ pos: 20, at: 3000 },
], // If data is not null, the pattern from data will be used. If data is null, the pattern from patternLink will be used. If both are null, an error will be returned.
}
])
// All the connected toys react to the first patternLink as default, cause no toyId defined.
// Connected toys: Lush 4, Nora, Domi 2.
lovensePattern.loadMultiplePatterns([
{
type: 'funScript',
patternLink: '[pattern link]',
toyId: '[Lush 4 toyId]',
},
{
type: 'funScript',
patternLink: '[pattern link]',
data: [
{ pos: 50, at: 1000 },
{ pos: 80, at: 2000 },
{ pos: 20, at: 3000 },
],// If data is not null, the pattern from data will be used. If data is null, the pattern from patternLink will be used. If both are null, an error will be returned.
toyId: '[Nora toyId]',
}
])// Lush 4 reacts to the first patternLink; Nora reacts to the second pattern data; Domi 2 does not vibrate.
// Connected toys: Lush 4, Nora, Domi 2.
lovensePattern.loadMultiplePatterns([
{
type: 'funScript',
patternLink: '[pattern link]',
toyId: '[Lush 4 toyId]',
},
{
type: 'funScript',
patternLink: '[pattern link]',
data: [
{ pos: 50, at: 1000 },
{ pos: 80, at: 2000 },
{ pos: 20, at: 3000 },
],// If data is not null, the pattern from data will be used. If data is null, the pattern from patternLink will be used. If both are null, an error will be returned.
}
])// Lush 4 reacts to the first patternLink; Nora and Domi 2 react to the second pattern data.
Step 4: Play Pattern
The event patternLoaded
will be triggered when the app (Lovense Remote or VibeMate) finishes loading Lovense patterns or patterns converted from Funscripts. Once you get the event patternLoaded
, call the lovensePattern.play method automatically, then the toy will start syncing to the media. This step is required every time your user connects to the app (Lovense Remote or VibeMate) to your platform, even when the audio/video is already playing.
Parameters | Description | Type | Required |
---|---|---|---|
speed | The media playback speed (1 is normal speed) | float | Yes |
currentTime | The current playback time of the video (in ms) | number | Yes |
lovensePattern.on("patternLoaded", () => {
console.log("patternLoaded")
// The pattern is ready to be played.
// When you play the video/audio content, call this method to play the pattern.
lovensePattern.play({
speed: 1, // The media playback speed (1 is normal speed)
currentTime: 1000, // The playing time duration so far (in ms)
})
})
Note: You only need to call lovensePattern.play within the event
patternLoaded
, when the eventpatternLoaded
is triggered for the first time.
Step 5: Sync with Video/Audio
Call this method when the media is paused.
// Pause the pattern when the media is paused or loading, so the toy's reaction matches the media content.
lovensePattern.pause()
Call this method when the media's progress bar or speed changes.
Parameters | Description | Type | Required |
---|---|---|---|
speed | The media playback speed (1 is normal speed) | float | Yes |
currentTime | The playing time duration so far (in ms) | number | Yes |
// If the speed or progress changes while playing the media, call this method to re-sync the speed and time.
lovensePattern.change({
speed: 1, // The media playback speed (1 is normal speed)
currentTime: 1000, // The playing time duration so far (in ms)
})
Optional API
lovensePattern.getPatternList
Get patterns by audio/video. If you only support one pattern per video, then there's no need to call it.
Parameters | Description | Type | Required |
---|---|---|---|
mediaId | The media's ID from your platform. videoId can also be used here. | string | Yes |
page | page | number | No |
pageSize | pageSize | number | No |
lovensePattern
.getPatternList({
mediaId: "[mediaId]",
// or videoId: "[mediaId]"
page: 1,
pageSize: 10,
})
.then((data) => {
console.log(data) // [patternList]
})
lovensePattern.exit
Call this method to disconnect Lovense Remote Or VibeMate from your platform.
lovensePattern.exit()
Events
Pattern Sync Error
Lovense Remote downloads patterns through HTTP requests. This event will be triggered when Lovense Remote or VibeMate fails to download a pattern.
lovensePattern.on("PatternSyncError", (data) => {
console.log("PatternSyncError", data.msg)
// According to the data.msg, you can check out the reasons and fix the issues.
// Missing parameter videoId or mediaId!
// Missing parameter ctoken!
// Missing parameter domId!
// Unable to read file, type: sync
// Can't Find Lovense Pattern for this media, the data can't be empty
// Unable to read file
// Can't Find Lovense Pattern for this media, Please create it from the Lovense Pattern editor page first.
// Pattern type is error!
// VibeMate Ai Sync Error
// Network error
})
App Disconnected
This event will be triggered when the server can't detect the app (Lovense Remote or VibeMate) for 85 seconds. This may happen, for example, when the app is closed or there is a network disconnection.
lovensePattern.on("appDisconnected", () => {
console.log("appDisconnected")
// You should update the Lovense Remote or VibeMate connection status on your website. We recommend showing a message to users that Lovense Remote or VibeMate is disconnected and prompting them to reconnect.
})
App Exit Pattern
This event is only triggered when there is an intentional disconnection from the app. For example, when the user clicks the "disconnect" button in the app (Lovense Remote or VibeMate), or when you call "lovensePattern.exit" on your website.
lovensePattern.on("appExitPattern", () => {
console.log("appExitPattern")
// Now you can update the App(Lovense Remote or VibeMate) connection status on your website, so the user can reconnect.
})
App Toy Status
This event will be triggered when toys connect or disconnect. It will list all the toys connected at that moment.
lovensePattern.on("appToyStatus", (data) => {
console.log("appToyStatus", data)
// [
// {
// nickName:"Dolce", //Toy nickName
// name:"dolce", //Toy name
// id:"dd83899c34d7", //Toy ID
// battery:100, //Toy battery
// version:"1", //Toy version
// status:"1" //Toy status 1:connected
// },
// {
// nickName:"Nora", //Toy nickName
// name:"nora", //Toy name
// id:"dd83899c34d7", //Toy ID
// battery:100, //Toy battery
// version:"1", //Toy version
// status:"1" //Toy status 1:connected
// }
//]
})
Create Lovense Patterns
VibeMate supports real-time pattern creation for videos, which does not require further development from you. However, if you want to support pattern creation from other browsers, you can use the following SDK to let users create Lovense patterns for audio/video files on your site's desktop version. This is optional and depends on your situation.
Workflow
Step 1: Integrate SDK
Click here to integrate the SDK.
Step 2: lovensePattern.editInit
Display the Lovense Pattern Editor panel to let users create patterns directly on your website. Currently supports one pattern per video.
Parameters | Description | Type | Required |
---|---|---|---|
ctoken | See here | string | Yes |
mediaId | The media's ID from your platform. | string | Yes |
domId | The Lovense Pattern Editor will be displayed in this domId. You can create a div, the domId will be the id of this div. | string | Yes |
videoEl | The <video> DOM element. Please make sure it has detected when you call this method. | object | Yes |
editorWidth | The width of the Lovense Pattern Editor panel, currently supported only by px , min-width: 720px | number | No |
lovensePattern.editInit({
ctoken: "[ctoken]",
mediaId: "[mediaId]",
// or videoId: "[mediaId]"
domId: "[domId]",
videoEl: document.querySelector("video"),
})