GithubHelp home page GithubHelp logo

Comments (6)

stonko1994 avatar stonko1994 commented on July 17, 2024 2

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.

protyposis avatar protyposis commented on July 17, 2024

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.

michael-riha avatar michael-riha commented on July 17, 2024

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.

vineetmimrot avatar vineetmimrot commented on July 17, 2024

Very much needed. Any timeline for supporting this feature?

from bitmovin-player-ui.

SInCE avatar SInCE commented on July 17, 2024

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.

noah1234j avatar noah1234j commented on July 17, 2024

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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.