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>
200_success
145k22 gold badges190 silver badges478 bronze badges
asked Feb 25, 2015 at 19:07
\$\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.

answered Feb 25, 2015 at 19:57
\$\endgroup\$
3
  • \$\begingroup\$ Thank you so much for an answer. Maybe you can help me also correct documentation in the code? \$\endgroup\$ 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\$ Commented Feb 26, 2015 at 4:41
  • \$\begingroup\$ If grammar or punctuation looks good it's also OK ;-) \$\endgroup\$ 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.

answered Mar 20, 2015 at 20:53
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.