html - 将嵌入式YouTube视频时间戳同步到自定义进度栏

标签 html css youtube timestamp embed

我陷入了今天一直在从事的项目的一部分。该任务是同步嵌入的youtube视频中的时间戳信息,并在页面底部显示与歌曲长度匹配的自定义进度栏。这是到目前为止的布局:

Progress Bar

因此,基本上,我如何获取固定的时间戳以更新进度,以及如何为栏设置动画以完成视频末尾的100%匹配。

我已经禁用了用户对嵌入的youtube视频进行草绘的功能。注意:用户也不能使用自定义进度栏更改youtube视频的时间(该时间仅用于可视队列)!

如果您需要更多说明,请告诉我。 HTML和CSS在下面。谢谢!! :)

HTML >>>

<!DOCTYPE html>
        <html>
            <head>
                <title>Chat</title>
                <link rel="stylesheet" href="main.css">
            </head>

            <body>

                <div class="header-bar">
                    <div class="bar"></div>
                    <div class="dropshadow"></div>
                </div>

                <div class="container-middle-third">
                    <div class="youtube-video" style="float: left;">
                        <div class="DJ-text">Affinity FM DJ Room</div>
                        <div class="DJ-underline"></div>
                        <div class="transparent-layer"> <iframe width="850px" height="477px" src="https://www.youtube.com/embed/2GvIq2SpVFM?autoplay=0&showinfo=0&controls=0" frameborder="0" allowfullscreen></iframe></div>


                    </div>

                    <div class="chat" style="float: left;">
                        <div class="Chat-text">Chat</div>
                        <div class="Chat-underline"></div>
                        <input type="text" class="chat-name" placeholder="Chat">
                        <div class="info-rect">Info</div>
                        <div class="chat-messages"></div>
                        <textarea placeholder="Join the conversation..."></textarea>
                        <div class="chat-status">Status: <span>Idle</span></div>
                    </div>
                </div>

                <div class="bottom-bar">

                    <div class="thumbnail" style="float: left"></div>
                    <div class="title-bar" style="float: left;">

                    <div class="song-name">Finding Hope - Let Go (feat. Deverano)</div>
                    <div class="dj-playing">Affinity FM is playing</div>

                    <div class="progress-background"></div>
                    <div class="progress-bar"></div>

                    </div>
                    <div class="subscribe" style="float: left;"></div>

                </div>

                <script src="http://127.0.0.1:8080/socket.io/socket.io.js"></script>

                <script>
                    (function() {
                        var getNode = function(s) {
                            return document.querySelector(s);
                        },

                        // Get required nodes
                        status = getNode('.chat-status span'),
                        messages = getNode('.chat-messages'), 
                        textarea = getNode('.chat textarea'),
                        chatName = getNode('.chat-name'),

                        statusDefault = status.textContent,    

                        setStatus = function(s){
                            status.textContent = s;

                            if(s !== statusDefault){
                                var delay = setTimeout(function(){
                                    setStatus(statusDefault);
                                    clearInterval(delay);
                                }, 3000);
                            }
                        };

                        //try connection
                        try{
                           var socket = io.connect('http://127.0.0.1:8080');
                        } catch(e){
                            //Set status to warn user
                        }

                        if(socket !== undefined){

                            //Listen for output
                            socket.on('output', function(data){
                                if(data.length){
                                    //Loop through results
                                    for(var x = 0; x < data.length; x = x + 1){
                                        var message = document.createElement('div');
                                        message.setAttribute('class', 'chat-message');
                                        message.textContent = ': ' + data[x].message;
                                        var name=document.createElement('span');
                                        name.setAttribute('class', 'userName');
                                        name.textContent = data[x].name;

                                        message.insertBefore(name, message.firstChild);

                                        //Append
                                        messages.appendChild(message);
                                        messages.insertBefore(message, messages.firstChild);
                                    }
                                }
                            });

                            //Listen for a status
                            socket.on('status', function(data){
                                setStatus((typeof data === 'object') ? data.message : data);

                                if(data.clear === true){
                                    textarea.value = '';
                                }
                            });

                            //Listen for keydown
                            textarea.addEventListener('keydown', function(event){
                                var self = this,
                                    name = chatName.value;

                                if(event.which === 13 && event.shiftKey === false){
                                    socket.emit('input', {
                                        name: name,
                                        message: self.value
                                    });
                                }
                            });
                        }

                    })();
                </script>
            </body>
        </html>

和CSS >>>
      body {
                background-color: #0f0f17;
                margin: 0px;
                width: 100%;
            }

.container-middle-third{
    margin-top: 20px;
    margin-left: 155px;
}

            body,
            textarea,
            input {
                font: 13px "Raleway", sans-serif;
                color: #ffffff;

            }

            .bar{
                height: 80px;
                width: 100%;
                background-color: #15151d;   
            }

            .DJ-text{
                font-weight: 700;
                /*position:relative;*/
                text-transform: uppercase;
            }

            .Chat-text{
                font-weight: 700;
                text-transform: uppercase;
            }

            .DJ-underline{
                width: 850px;
                height: 1px;
                position:relative;top:10px;
                background-color: #3f3f45;
                margin: 0px 0px 40px;
            }

            .Chat-underline{
                width: 100%;
                position:relative;
                /*left:-140px;*/
                float:right;
                height: 1px;
                position:relative;top:10px;
                background-color: #3f3f45;
                margin: 0px 0px 40px;
            }
            .transparent-layer{
                width: 850px;
                height: 477px;
                pointer-events: none;
                background-color: #ffffff;
            }

            .ad{
                width: 728px;
                height: 90px;
                border: 1px solid #000000;
                margin-left: 11px;
                margin-top: 20px;
            }

            .chat {
                min-width: 400px;
                margin: 0px 0px 0px 135px;
            }
            .chat-messages,
            .chat-textarea,
            .chat-name {
                border: 1px solid #1a1a23;
                background-color: #1a1a23;
            }

            .userName{
                font-weight: 700;
                color: #079ce0;
            }

            .chat-messages {
                width:380px;
                height:400px;
                overflow-y:scroll;
                padding:10px;
            }

            .chat-message {
                margin-bottom:10px;
            }

            .info-rect{
                height: 40px;
                width: 180px;
                padding:10px;
                max-width: 100%;
                margin:0;
                border:0;
                display: flex; 
                align-items: center;
                justify-content: center;  
                font-weight: 700;
                text-transform: uppercase;
                background-color: #15151d
            }

            .chat-name{
                height: 40px;
                max-width: 100%;
                width: 180px;
                padding:10px;
                border:0;
                margin:0;
                font-weight: 700;
                text-transform: uppercase;
                float:left;
                text-align: center;
            }

            .chat textarea {
                width:380px;
                padding:10px;
                margin:0;
                border-top:0;
                max-width:100%;
                border-top: 1px solid #0f0f17;
                border-bottom: 1px solid #1a1a23;
                border-right: 1px solid #1a1a23;
                border-left: 1px solid #1a1a23;
                background-color: #1a1a23;

            }

            .chat-status {
                color: #bbb;
                opacity: 0;
                background-color: #0f0f17;
            }

            .info-rect,
            .chat textarea,
            .chat-name { 
                max-width: 100%; 
            }


            .bottom-bar{
                position: fixed;
                bottom: 0;
                width: 100%;
            }

            .thumbnail{
                width: 80px;
                height: 80px;
                background-color: #ffffff
            }   

            .title-bar{
                width:1000px;
                height: 80px;
                background-color: #1a1a23;
            }
            .song-name{
                font-weight: 700;
                text-transform: uppercase;
                margin-left: 30px;
                margin-top: 25px;
            }
            .dj-playing{
                margin-left: 30px;
            }
            .progress-background{
                width: 1000px;
                height: 4px;
                background-color: #313139;
                position: fixed;
                bottom: 0;
            }
            .progress-bar{
                width: 400px;
                height: 4px;
                background-color: #fa1d57;
                position: fixed;
                bottom: 0;
            }
            .subscribe{
                width: 520px;
                height: 80px;
                background-color: #15151d;
            }

最佳答案

爱你的问题!

  • 使用带有id="player"的div切换iframe(任意名称,它可以是“my_own_player”或“XYZ_player” ...)
    然后,您已经准备就绪,可以将iframe播放器转换为Youtube播放器对象,以便使用“IFrame播放器API”完成所需的操作。
  • 确保以与iframe相同的方式设置div的样式。
  • 只需添加以下脚本:
    //This function creates an <iframe> (and YouTube player)
    function onYouTubeIframeAPIReady()
    {
        player = new YT.Player("player",
        {
            height: "850",
            width: "477",
            videoId: "2GvIq2SpVFM",
            events:
            {
                "onReady": onPlayerReady,
                "onStateChange": onPlayerStateChange
            }
        });
    }
    
  • 用您的视频ID替换videoId
  • 用视频的高度替换height
  • 用视频的宽度替换width

  • 现在,按照您的要求获取“视频时间戳” ,以便使进度条变得容易。播放器对象有两种方法可以做到这一点:
  • getCurrentTime()
  • getDuration()
  • getDuration是视频的总时间(以秒为单位)。 getCurrentTime是视频播放的时间。划分getCurrentTimegetDuration,您将获得进度条的比率。将其乘以100,即可得到所需的百分比:
    (player.getCurrentTime()/player.getDuration())*100;
    

    而已!一旦获得代表 getCurrentTime / getDuration 的百分比,就不需要其他任何东西来生成html进度条。只需将html栏元素的宽度设置为该百分比即可。只需确保红色的“酒吧”有一个背景(另一个div),该背景很容易被视为进度条的向外限制。或者只是将其放在页面上可见的另一个div之内,如下所示:
    <div id="progress" style="width: 800px; height: 10px; border: 1px solid #fff;">
        <div id="bar" style="width: 1px; height: 10px; background: #f00;"></div>
    </div>
    

    请,只需尝试修改后的HTML:

    <!DOCTYPE html>
    <html>
      <head>
        <title>Chat</title>
        <link rel="stylesheet" href="main.css">
      </head>
    
      <body>
    
        <div class="header-bar">
          <div class="bar"></div>
          <div class="dropshadow"></div>
        </div>
    
        <div class="container-middle-third">
          <div class="youtube-video" style="float: left;">
            <div class="DJ-text">Affinity FM DJ Room</div>
            <div class="DJ-underline"></div>
            <div class="transparent-layer"> <div id="player" style="width: 850px; height: 477px;"></div></div>
    
    
          </div>
    
          <div class="chat" style="float: left;">
            <div class="Chat-text">Chat</div>
            <div class="Chat-underline"></div>
            <input type="text" class="chat-name" placeholder="Chat">
            <div class="info-rect">Info</div>
            <div class="chat-messages"></div>
            <textarea placeholder="Join the conversation..."></textarea>
            <div class="chat-status">Status: <span>Idle</span></div>
          </div>
        </div>
    
        <div class="bottom-bar">
    
          <div class="thumbnail" style="float: left"></div>
          <div class="title-bar" style="float: left;">
    
            <div class="song-name">Finding Hope - Let Go (feat. Deverano)</div>
            <div class="dj-playing">Affinity FM is playing</div>
    
            <div class="progress-background">
              <div id="progress-bar" class="progress-bar"></div>
            </div>
    
          </div>
          <div class="subscribe" style="float: left;"></div>
    
        </div>
    
        <script src="http://127.0.0.1:8080/socket.io/socket.io.js"></script>
    
        <script>
          (function() {
            var getNode = function(s) {
              return document.querySelector(s);
            },
    
                // Get required nodes
                status = getNode('.chat-status span'),
                messages = getNode('.chat-messages'), 
                textarea = getNode('.chat textarea'),
                chatName = getNode('.chat-name'),
    
                statusDefault = status.textContent,    
    
                setStatus = function(s){
                  status.textContent = s;
    
                  if(s !== statusDefault){
                    var delay = setTimeout(function(){
                      setStatus(statusDefault);
                      clearInterval(delay);
                    }, 3000);
                  }
                };
    
            //try connection
            try{
              var socket = io.connect('http://127.0.0.1:8080');
            } catch(e){
              //Set status to warn user
            }
    
            if(socket !== undefined){
    
              //Listen for output
              socket.on('output', function(data){
                if(data.length){
                  //Loop through results
                  for(var x = 0; x < data.length; x = x + 1){
                    var message = document.createElement('div');
                    message.setAttribute('class', 'chat-message');
                    message.textContent = ': ' + data[x].message;
                    var name=document.createElement('span');
                    name.setAttribute('class', 'userName');
                    name.textContent = data[x].name;
    
                    message.insertBefore(name, message.firstChild);
    
                    //Append
                    messages.appendChild(message);
                    messages.insertBefore(message, messages.firstChild);
                  }
                }
              });
    
              //Listen for a status
              socket.on('status', function(data){
                setStatus((typeof data === 'object') ? data.message : data);
    
                if(data.clear === true){
                  textarea.value = '';
                }
              });
    
              //Listen for keydown
              textarea.addEventListener('keydown', function(event){
                var self = this,
                    name = chatName.value;
    
                if(event.which === 13 && event.shiftKey === false){
                  socket.emit('input', {
                    name: name,
                    message: self.value
                  });
                }
              });
            }
    
          })();
        </script>
        <script>
          var time_total;
          var timeout_setter;
          var player;
          var tag = document.createElement("script");//This code loads the IFrame Player API code asynchronously
    
          tag.src = "https://www.youtube.com/iframe_api";
          var firstScriptTag = document.getElementsByTagName("script")[0];
          firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    
          //This function creates an <iframe> (and YouTube player) OR uses the iframe if it exists at the "player" element after the API code downloads
          function onYouTubeIframeAPIReady()
          {
            player = new YT.Player("player",
                                   {
              height: "850",
              width: "477",
              videoId: "2GvIq2SpVFM",
              events:
              {
                "onReady": onPlayerReady,
                "onStateChange": onPlayerStateChange
              }
            });
          }
          //The API will call this function when the video player is ready
          function onPlayerReady(event)
          {
            event.target.playVideo();
            time_total  = convert_to_mins_and_secs(player.getDuration(), 1);
            loopy();
          }
    
          function loopy()
          {
            var current_time = convert_to_mins_and_secs(player.getCurrentTime(), 0);
            document.getElementById("progress-bar").style.width = (player.getCurrentTime()/player.getDuration())*100+"%";
            console.log( current_time + " / " + time_total);
            timeout_setter = setTimeout(loopy, 1000);
          }
    
          function convert_to_mins_and_secs(seconds, minus1)
          {
            var mins    = (seconds>=60) ?Math.round(seconds/60):0;
            var secs    = (seconds%60!=0) ?Math.round(seconds%60):0;
            var secs    = (minus1==true) ?(secs-1):secs; //Youtube always displays 1 sec less than its duration time!!! Then we have to set minus1 flag to true for converting player.getDuration()
            var time    = mins + ":" + ((secs<10)?"0"+secs:secs);
            return time;
          }
    
          // 5. The API calls this function when the player's state changes
          function onPlayerStateChange(event)
          {
            if (event.data == YT.PlayerState.ENDED)
            {
              console.log("END!");
              clearTimeout(timeout_setter);
            }
            else
            {
              console.log(event.data);
            }
          }
        </script>
    
      </body>
    </html>
    

    使用CSS:

    body {
      background-color: #0f0f17;
      margin: 0px;
      width: 100%;
    }
    
    .container-middle-third{
      margin-top: 20px;
      margin-left: 155px;
    }
    
    body,
    textarea,
    input {
      font: 13px "Raleway", sans-serif;
      color: #ffffff;
    
    }
    
    .bar{
      height: 80px;
      width: 100%;
      background-color: #15151d;   
    }
    
    .DJ-text{
      font-weight: 700;
      /*position:relative;*/
      text-transform: uppercase;
    }
    
    .Chat-text{
      font-weight: 700;
      text-transform: uppercase;
    }
    
    .DJ-underline{
      width: 850px;
      height: 1px;
      position:relative;top:10px;
      background-color: #3f3f45;
      margin: 0px 0px 40px;
    }
    
    .Chat-underline{
      width: 100%;
      position:relative;
      /*left:-140px;*/
      float:right;
      height: 1px;
      position:relative;top:10px;
      background-color: #3f3f45;
      margin: 0px 0px 40px;
    }
    .transparent-layer{
      width: 850px;
      height: 477px;
      pointer-events: none;
      background-color: #ffffff;
    }
    
    .ad{
      width: 728px;
      height: 90px;
      border: 1px solid #000000;
      margin-left: 11px;
      margin-top: 20px;
    }
    
    .chat {
      min-width: 400px;
      margin: 0px 0px 0px 135px;
    }
    .chat-messages,
    .chat-textarea,
    .chat-name {
      border: 1px solid #1a1a23;
      background-color: #1a1a23;
    }
    
    .userName{
      font-weight: 700;
      color: #079ce0;
    }
    
    .chat-messages {
      width:380px;
      height:400px;
      overflow-y:scroll;
      padding:10px;
    }
    
    .chat-message {
      margin-bottom:10px;
    }
    
    .info-rect{
      height: 40px;
      width: 180px;
      padding:10px;
      max-width: 100%;
      margin:0;
      border:0;
      display: flex; 
      align-items: center;
      justify-content: center;  
      font-weight: 700;
      text-transform: uppercase;
      background-color: #15151d
    }
    
    .chat-name{
      height: 40px;
      max-width: 100%;
      width: 180px;
      padding:10px;
      border:0;
      margin:0;
      font-weight: 700;
      text-transform: uppercase;
      float:left;
      text-align: center;
    }
    
    .chat textarea {
      width:380px;
      padding:10px;
      margin:0;
      border-top:0;
      max-width:100%;
      border-top: 1px solid #0f0f17;
      border-bottom: 1px solid #1a1a23;
      border-right: 1px solid #1a1a23;
      border-left: 1px solid #1a1a23;
      background-color: #1a1a23;
    
    }
    
    .chat-status {
      color: #bbb;
      opacity: 0;
      background-color: #0f0f17;
    }
    
    .info-rect,
    .chat textarea,
    .chat-name { 
      max-width: 100%; 
    }
    
    
    .bottom-bar{
      position: fixed;
      bottom: 0;
      width: 100%;
    }
    
    .thumbnail{
      width: 80px;
      height: 80px;
      background-color: #ffffff
    }   
    
    .title-bar{
      width:1000px;
      height: 80px;
      background-color: #1a1a23;
    }
    .song-name{
      font-weight: 700;
      text-transform: uppercase;
      margin-left: 30px;
      margin-top: 25px;
    }
    .dj-playing{
      margin-left: 30px;
    }
    .progress-background{
      width: 1000px;
      height: 4px;
      background-color: #313139;
      position: fixed;
      bottom: 0;
    }
    .progress-bar{
      width: 400px;
      height: 4px;
      background-color: #fa1d57;
      position: fixed;
      bottom: 0;
    }
    .subscribe{
      width: 520px;
      height: 80px;
      background-color: #15151d;
    }
    

    或者只是看看结果:
    http://lespointscom.com/a/misc/demo/2016_06_19/main.html

    IFrame播放器API引用:
    https://developers.google.com/youtube/iframe_api_reference#Loading_a_Video_Player

    关于html - 将嵌入式YouTube视频时间戳同步到自定义进度栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37904499/

    相关文章:

    html - Gulp 内联更改 HTML 标记的大小写

    html - 我无法在辅助方法中调整 html.EditorFor 框的宽度

    css - DIV 环绕 100% 高度的 IMG

    youtube - 使用 YouTube API 播放带有开始和结束时间的 YouTube 视频

    html - youtube-dl 不适用于所有 YouTube 视频

    c# - 为什么我不能在720HD中嵌入youtube或在Windows 8 Webview中使用全屏按钮?

    javascript - 与其他浏览器相比,IE/Edge 样式的应用顺序不同

    html - 伪边界从父级溢出 : auto

    同一页面上的 Javascript 响应

    html - 相对于容器的字体大小百分比