4
\$\begingroup\$

I do HTML5 Video player with some controls. I have a button, where I change classname for make play, pause or replay button. I have a mute/unmute button, volume range slider, timer and fullscreen mode button.

Maybe I can do some functions better or faster, and also, maybe I need to change comments?

Logic:

"use strict"
doc = document

video = doc.getElementById("video")

video.controls = false

###* Video controls ###
play_button         = doc.getElementById("play-button")
progress_bar        = doc.getElementById("progress-bar")
progress_load       = doc.getElementById("progress-load")
current_time_block  = doc.getElementById("time-current")
duration_block = doc.getElementById("time-duration")
volume_button       = doc.getElementById("volume-button")
volume_range        = doc.getElementById("volume-range")
screen_button       = doc.getElementById("screen-button")

###*
# A video DOM currentTime property formatting.
# @param {current_time} Video currentTime property.
# @return {string} Time in the format 00:00.
####
video_time_format = (current_time) ->
  seconds = Math.floor(current_time)
  minutes = Math.floor(current_time / 60)
  if minutes >= 10 then minutes = minutes else minutes = "0" + minutes
  if seconds >= 10 then seconds = seconds else seconds = "0" + seconds
  minutes + ":" + seconds

###* Get a video DOM duration property. ###
video_duration = null
get_video_duration = ->
  if video.duration
    video_duration = video.duration

###* Set video duration to video controls panel. ###
video.addEventListener("loadedmetadata", ->
  duration_block.textContent = video_time_format(get_video_duration())
)

###* 
# A helper function for update progress bar events.
# Set video current time in video controls panel and progress bar.
# @param {position} Percentage of progress.
###
current_time_update = (position) ->
  current_time_block.textContent = video_time_format(video.currentTime)
  progress_load.style.width = position

###*
# The value is converted into a percentage value using the video’s duration
# and currentTime.
###
video.addEventListener("timeupdate", ->
  current_time_update(Math.floor((100 / video_duration) *
    video.currentTime) + "%"))

###*
# A clickable progress bar.
# Get x-coordinate of the mouse pointer, converted its into a time.
###
progress_bar.addEventListener "click", ((event) ->
  mouseX = event.offsetX
  video.currentTime = mouseX * video_duration / progress_bar.offsetWidth
  current_time_update(mouseX + "px")
), false

###*
# Start playback and change replay button to pause button.
####
video_replay = ->
  video.currentTime = 0
  video.play()
  play_button.classList.remove("md-replay")
  play_button.classList.add("md-pause")

###*
# Rests video to start position and change play button to pause button.
####
video_play = ->
  video.play()
  play_button.classList.remove("md-play-arrow")
  play_button.classList.add("md-pause")

###*
# A nearest integer of video DOM currentTime property pluralize.
# @param {current_time} A nearest integer of video DOM currentTime property.
# @return {string} A pluralized time with title.
####
pluralize_time = (current_time) ->
  cases = [2, 0, 1, 1, 1, 2]
  index = if current_time % 100 > 4 && current_time % 100 < 20 then 2 else
    cases[Math.min(current_time % 10, 5)]
  first_titles = ["Просмотрена ", "Просмотрено ", "Просмотрено "]
  second_titles = [" секунда", " секунды", " секунд"]
  first_titles[index] + current_time + second_titles[index]

###*
# Stop playback and change pause button to play button.
####
video_pause = ->
  video.pause()
  play_button.classList.remove("md-pause")
  play_button.classList.add("md-play-arrow")
  console.log pluralize_time(Math.floor(video.currentTime))

play_pause_toggle = ->
  if video.ended
    video_replay()
  else if video.paused
    video_play()
  else
    video_pause()

play_button.addEventListener("click", play_pause_toggle)
video.addEventListener("click", play_pause_toggle)

###* Change pause button to play. ####
video.addEventListener("ended", -> 
  play_button.classList.remove("md-pause")
  play_button.classList.add("md-replay")
)

###*
# Sound turned on when volume button pressed.
# Change `volume-off` button to `volume-up`.
####
video_volume_unmuted = ->
  video.muted = false
  volume_button.classList.remove("md-volume-off")
  volume_button.classList.add("md-volume-up")

###*
# Sound turned off when volume button pressed.
# Change `volume-up` button to `volume-off`.
####
video_volume_muted = ->
  video.muted = true
  volume_button.classList.remove("md-volume-up")
  volume_button.classList.add("md-volume-off")

###*
# Sound turned on when sound is off and user press shortcut for unmute volume.
# Call `video_volume_unmuted()` function.
####
video_volume_on = ->
  video.volume = 0.1
  volume_range.value = 0.1
  video_volume_unmuted()

###*
# Sound turned off when slider control off.
# Change `volume-up` button to `volume-off`.
####
video_volume_off = ->
  video.volume = 0
  volume_button.classList.remove("md-volume-up")
  volume_button.classList.add("md-volume-off")

###* Sound turned on or off. ###
volume_toggle = ->
  if video.volume == 0
    video_volume_on()
  else if video.muted
    video_volume_unmuted()
  else
    video_volume_muted()

volume_button.addEventListener("click", volume_toggle)

change_volume = ->
  volume_range_value = parseFloat(volume_range.value)
  if volume_range_value == 0
    video_volume_off()
  else
    video.volume = volume_range_value
    video_volume_unmuted()

volume_range.addEventListener("input", change_volume)

###*
# Launch into full screen mode.
# Change `md-fullscreen` button to `md-fullscreen-exit`.
####
launch_into_full_screen = ->
  screen_button.classList.remove("md-fullscreen")
  screen_button.classList.add("md-fullscreen-exit")
  if video.requestFullscreen
    video.requestFullscreen()
  else if video.mozRequestFullScreen
    video.mozRequestFullScreen()
  else if video.webkitRequestFullscreen
    video.webkitRequestFullscreen()

###*
# Exit full screen mode.
# Change `md-fullscreen-exit` button to `md-fullscreen`.
####
exit_full_screen = ->
  screen_button.classList.remove("md-fullscreen-exit")
  screen_button.classList.add("md-fullscreen")
  if video.exitFullscreen
    video.exitFullscreen()
  else if video.mozCancelFullScreen
    video.mozCancelFullScreen()
  else if video.webkitExitFullscreen
    video.webkitExitFullscreen()

###* Launching and existing fullscreen mode. ###
full_screen_toggle = ->
  if !video.fullscreenElement && !video.mozFullScreenElement && !video.webkitFullscreenElement
    launch_into_full_screen()
  else
    exit_full_screen()

screen_button.addEventListener("click", full_screen_toggle)

###* Shortcuts. ###
doc.onkeydown = (event) ->
  play_pause_toggle() if event.keyCode == 32
  full_screen_toggle() if event.keyCode == 70
  volume_toggle() if event.keyCode == 77
  video_replay() if event.keyCode == 48

Layout:

<div class="custom-video">
    <video id="video">
      <source src="http://media.w3.org/2010/05/sintel/trailer.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
      <source src="http://media.w3.org/2010/05/sintel/trailer.webm" type='video/webm; codecs="vp8, vorbis"' />
    </video>

    <div class="video-controls cf">
      <div id="progress-bar" class="progress-bar">
        <div id="progress-load" class="progress-load"></div>
      </div>

      <div id="play-button" class="video-control-button md-2x md-play-arrow left">
      </div>

      <div id="volume-controls-wrapper" class="volume-controls-wrapper left">
        <div id="volume-button" class="video-control-button md-2x md-volume-up left">
        </div>

        <input type="range" id="volume-range" class="video-control-range left" min="0" max="1" step="0.1" value="1">
      </div>

      <div class="time-display left">
        <span id="time-current" class="time-current">00:00</span>
        <span class="time-separator">/</span>
        <span id="time-duration" class="time-duration">00:00</span>
  </div>

  <div id="screen-button" class="video-control-button md-2x md-fullscreen right">
  </div>
</div>

\$\endgroup\$
0

2 Answers 2

2
\$\begingroup\$

Your HTML looks good, except for a missing </div> brace. You can validate it at the W3C HTML Validator.

While this appears to be a snippet, you should structure your HTML files like this, in the case you are not already:

<!doctype html>
<html>
    <head>
        <title>Page Title Here...</title>
    </head>
    <body>
        <!-- Content Here... -->
    </body>
</html>

Right here, I would not align your code like this, it is easier to write and makes just as much sense without those extra spaces:

play_button         = doc.getElementById("play-button")
progress_bar        = doc.getElementById("progress-bar")
progress_load       = doc.getElementById("progress-load")
current_time_block  = doc.getElementById("time-current")
duration_block = doc.getElementById("time-duration")
volume_button       = doc.getElementById("volume-button")
volume_range        = doc.getElementById("volume-range")
screen_button       = doc.getElementById("screen-button")

Your indentation, spacing, and naming are excellent, although I prefer a 4-space indent over a 2-space indent. I do not know CoffeeScript or JavaScript, so I cannot make any more comments.

\$\endgroup\$
3
  • \$\begingroup\$ Thank you so much for an answer. Maybe you can help me also correct documentation in the code? \$\endgroup\$
    – rel1x
    Commented Feb 26, 2015 at 3:29
  • \$\begingroup\$ @pertpoert Your documentation looks good to me. Do you mean style, grammar/punctuation, or accuracy? Your style and grammar/punctuation looks good, and they appear to be correct, but I can't read the code perfectly. \$\endgroup\$
    – user34073
    Commented Feb 26, 2015 at 4:41
  • \$\begingroup\$ If grammar or punctuation looks good it's also OK ;-) \$\endgroup\$
    – rel1x
    Commented Feb 26, 2015 at 7:58
0
\$\begingroup\$

mark up your content using the correct and correlating html elements for each case. this benefits users in terms of accessibilty, and usability, which benefits your bottom line.
in this case, you can use input ranges for your progress bar (just like the volume bar), you can use buttons instead of divs as buttons, and you can implement the time element in place of the divs there too.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.