Comments (6)
Maybe we could also add some behavior for mobile if you double tab left or right on the screen to apply this functionality.
from bitmovin-player-ui.
That could also be added to the HugePlaybackButton
overlay, but then how do we differentiate between a double-tap-to-fullscreen and double-tap-to-skip? Split the screen into 3 regions and skip on outer taps?
from bitmovin-player-ui.
Ob mobile you should look how VLC (Android) and youtube (native) is handling this, it is perfect.
No button just double tab or swipe on the screen.
That is a perfect UX!
from bitmovin-player-ui.
Very much needed. Any timeline for supporting this feature?
from bitmovin-player-ui.
An example about how to add these buttons yourself can be found in our Web-Samples Repository: https://github.com/bitmovin/bitmovin-player-web-samples/blob/main/playerUi/customForwardRewindButtons.html
from bitmovin-player-ui.
This answer isn't super well formatted and I haven't gone through and removed any nonrelevant code. But this would have helped me two days ago so I'm posting here.
I have implemented something along these lines as youtube does. I tied into player click overly and divided it into thirds, tap the front twice it skips forward 5 sec, three times = 10 sec etc. A single tap pauses/plays.
Here is some code if it is useful to anyone
I am doing this in vue3 composition API not sure what everyone else is doing.
I import my node libraries
import { Player } from 'bitmovin-player' import { PlaybackToggleOverlay, UIContainer, UIManager, Container, Button, FullscreenToggleButton, VolumeToggleButton, Spacer, SettingsToggleButton, VolumeSlider, SeekBar, ControlBar, PlaybackToggleButton, PictureInPictureToggleButton, SettingsPanel, SettingsPanelPage, SettingsPanelItem, VideoQualitySelectBox, PlaybackTimeLabel, PlaybackTimeLabelMode, ClickOverlay, SeekBarLabel, PlayerUtils } from 'bitmovin-player-ui'
Here i setup my reactive data as you do in vue
`
//This stuff is for stephans skip magic
const clickCount = ref(0) //This is used for Stephans request the YoutubeLike Skip Feature
const skipIntervals = ref({
1: 5, //First click skips 5 seconds etc...
2: 10,
3: 20,
4: 40,
5: 80,
6: 160,
7: 320,
8: 640,
9: 1280
})
let player = {}
`
This function builds out the player using their UI libarary
`
const setup = () => {
try {
let clickOverlay = new ClickOverlay()
clickOverlay.onClick.subscribe((event, ev)=> {
})
//Starts Building the UI - Settings Panel
let mainSettingsPanelPage = new SettingsPanelPage({
components: [
new SettingsPanelItem('Quality', new VideoQualitySelectBox()),
],
});
let settingsPanel = new SettingsPanel({
components: [
mainSettingsPanelPage,
],
hidden: true,
});
//Control Bar UI Build
let controlBar = new ControlBar({
components: [
settingsPanel,
new Container({
components: [
new PlaybackTimeLabel({ timeLabelMode: PlaybackTimeLabelMode.CurrentTime, hideInLivePlayback: true }),
new SeekBar({ label: new SeekBarLabel() }),
new PlaybackTimeLabel({ timeLabelMode: PlaybackTimeLabelMode.TotalTime, cssClasses: ['text-right'] }),
],
cssClasses: ['controlbar-top'],
}),
new Container({
components: [
new PlaybackToggleButton(),
new VolumeToggleButton(),
new VolumeSlider(),
new Spacer(),
new FullscreenToggleButton(),
new PictureInPictureToggleButton(),
new SettingsToggleButton({ settingsPanel: settingsPanel }),
],
cssClasses: ['controlbar-bottom'],
}),
],
});
//Player UI
const PlayerUI = new UIContainer({
components: [
new PlaybackToggleOverlay(),
clickOverlay,
controlBar,
],
hideDelay: 2000,
hidePlayerStateExceptions: [
PlayerUtils.PlayerState.Prepared,
PlayerUtils.PlayerState.Paused,
PlayerUtils.PlayerState.Finished,
],
});
//Builds the PLayer
player = new Player(wltBitmovin.value, conf.value);
//UI Manager
new UIManager(player, PlayerUI)
// Abstract the source loading
player.load(source.value).then(function () {
console.log('Successfully loaded source');
}, function () {
console.log('Error while loading source');
});
} catch (err) {
console.log(err)
}
}`
This function allows keyboard control as follows:
space=play/pause
uparrow=volup
downarrow=voldown
rightarrow=skip x seconds forward
leftarrow=skip x seconds back
` const checkKey = (e) => {
if (e.keyCode == '32') {
player.isPlaying() ? player.pause() : player.play()
}
if (e.keyCode == '38') {
player.setVolume(player.getVolume() + 10)
}
else if (e.keyCode == '40') {
player.setVolume(player.getVolume() - 10)
}
else if (e.keyCode == '37') {
if (clickCount.value == 0) delayedClickSkip("backward", event.target)
clickCount.value ++
}
else if (e.keyCode == '39') {
if (clickCount.value == 0) delayedClickSkip("forward", event.target)
clickCount.value ++
}
}`
The below three functions are what make the 1/3 taps happen
The first function plays if the player isn't already playing. It then senses where the mouse was clicked, determines the third and reacts accordingly.
The second function is the timeout function essentially it gives you 1 second to click as many times as you want then interperts the number of clicks as how many seconds to jump forward.
The third function appends a visual indication of the skip.
`
const magicThirdsSkippyThingy = (event) => {
//triggers when overlay is clicks
let width = event.target.offsetWidth
let eventoffset = event.offsetX
if (eventoffset == 0) return //This is a bugfix for the space bar triggering click function
//Makes sure you can see controls as they're hidden initially
showPlayerControls()
//IF player is not playing, the whole will act as a play button
if (!player.isPlaying()) {player.play(); return}
//From here on the screen will be divided into thirds
//MIDDLE THIRD
if (eventoffset >= width/3 && eventoffset <= width/3*2) {
(!player.isPlaying()) ? player.play(): player.pause() //toggles play and pause
return
}
//LEFT THird
if (eventoffset <= width/3) {
if (clickCount.value == 0) delayedClickSkip("backward", event.target)
clickCount.value ++
}
//Right Third
if (eventoffset >= width - width/3) {
if (clickCount.value == 0) delayedClickSkip("forward", event.target)
clickCount.value ++
}
}
const delayedClickSkip = (direction, target) => {
let time = 1 //in sec
setTimeout(() => {
if (direction == "backward") {
backward(skipIntervals.value[clickCount.value])
appendDirectionIndicator(target, skipIntervals.value[clickCount.value], "backward")
}
if (direction == "forward") {
forward(skipIntervals.value[clickCount.value])
appendDirectionIndicator(target, skipIntervals.value[clickCount.value], "forward")
}
clickCount.value = 0 //resets the clicks
}, time * 1000);
}
const appendDirectionIndicator = (elem, time, direction) => {
//removes all old forward indicatiors for when skipping in rapid succession
const elementsToRemove = document.querySelectorAll('.tempDirSplash');
elementsToRemove.forEach(element => {
element.remove();
})
//Builds out the forward and back buttons html
let html = `
<div class="tempDirSplash ${direction}" >
<div class="splashContent ${player.getViewMode() == "inline" ? "smallscreen" : "" }">
<img src="../../../public/${direction == "forward" ? "forward_button.svg" : "rewind_button.svg"}" alt="My Happy SVG"/>
</svg>
<p>${time} SEC</p>
</div>
</div>
`
elem.innerHTML += html
//delays 2 seconds then removes the forward and back
let splash = document.querySelectorAll('.tempDirSplash')[0]
setTimeout(()=> {
if (!splash) return
if (splash.length == null) return
splash.remove();
}, 2000)
}
Here is some sass that I used as well
<style lang="scss">
.bmpui-ui-clickoverlay {
display: relative;
}
.tempDirSplash {
pointer-events: none;
width: 15%;
z-index: 2;
height: 100%;
background-color: rgba(128, 128, 128, 0.055);
position: absolute;
padding-left: 10px;
padding-right: 10px;
top: 0;
display: flex;
justify-content: center;
align-items: center; /* Vertically center align */
animation: fadeOut 2.5s forwards;
&.forward {
right: 0px;
border-bottom-left-radius: 100% 50%;
border-top-left-radius: 100% 50%;
z-index: 0;
}
&.backward {
left: 0;
border-top-right-radius: 100% 50%;
border-bottom-right-radius: 100% 50%;
}
.splashContent {
pointer-events: none;
color: white;
img {
height: 50px !important;
}
p {
font-size: 20px;
}
&.smallscreen {
img {
height: 26px !important;
}
p {
font-size: 14px;
}
}
}
}
@Keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
@import 'bitmovin-player-ui/dist/css/bitmovinplayer-ui.min.css';
`
from bitmovin-player-ui.
Related Issues (20)
- How to make autoplay keep fullscreen mode?
- npm ERR! Build failed with error code: 1 while running npm install HOT 2
- Full screen button on player for Android App
- Bitmovin encoding distorts colors HOT 1
- Livestream stutters at higher playback speed HOT 1
- Overlapping Subtitle Queues break Subtitles in Safari HOT 1
- getMaxTimeShift value is negative non-zero for Safari HLS live streams HOT 1
- Feature Request: Use Document Picture-in-Picture Web API HOT 4
- pausedTimeshiftUpdater is not cleared HOT 2
- Accessing UIManager when replacing the built-in UI through location HOT 3
- I want to update the version of player HOT 1
- bleacherreport.com - impossible to go to exit fullscreen HOT 9
- when the UI autohides with the SettingsPanel open, one touch is need to make the visible SettingsPanel interactive again HOT 2
- seekbar markers overflowing player in some UI configurations HOT 3
- overlapping issue with seekbar thumbnails HOT 1
- error ReferenceError: self is not defined HOT 4
- <button> should not have superfluous aria attributes HOT 1
- listbox does not implement listbox a11y pattern HOT 1
- immediately hide UI if mouse leaves uicontainer HOT 2
- google chromecast HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from bitmovin-player-ui.