顯示視訊的持續時間、目前時間和剩餘時間

上次更新: 2023-09-21

您可以使用瀏覽器TVSDK來擷取您可在搜尋列上顯示的媒體相關資訊。

  1. 請等候播放器至少處於「已準備」狀態。

  2. 使用擷取目前的播放點時間 MediaPlayer.currentTime 屬性。

    此屬性會傳回虛擬時間軸上目前的播放點位置(以毫秒為單位)。 此時間是相對於已解析資料流而計算的,該資料流可能包含多個替代內容的例項,例如多個廣告或拼接到主資料流中的廣告插播。 對於即時/線性串流,傳回的時間一律在播放視窗範圍內。

    MediaPlayer.currentTime
    
  3. 擷取資料流的播放範圍並決定持續時間。

    1. 使用 mediaPlayer.playbackRange 屬性以取得虛擬時間軸時間範圍。

    2. 若要決定持續時間,請從範圍的結尾減去開始時間。

      這包括插入資料流(廣告)中的其他內容持續時間。

      對於VOD,範圍一律從零開始,而結束值等於主要內容持續時間與插入到資料流(廣告)中之其他內容持續時間的和。

      對於線性/即時資產,範圍表示播放視窗範圍,此範圍在播放期間會變更。

  4. 使用MediaPlayer和瀏覽器TVSDK元素上可用的方法來設定搜尋列引數。

    例如,以下是以HTML顯示搜尋列的可能配置。

    <div class="seekbar" id="seekbar">
         <div>
            <span class="backer" id="backer"></span>
            <span class="buffer" id="buffer" ></span>
            <div class="playhead" id="playhead"></div>
                      <span class="progress" id="progress" ></span>
            </div>
          </div>
      </div>
    

    以下是對應的css:

    #seekbar {
          position: relative;
          width: 100%;
          height: 16px;
          cursor: pointer;
          background: transparent;
    }
    
    #seekbar div {
          position: relative;
          height: 100%;
          margin-left: 8px;
          margin-right: 8px;
    }
    
    #seekbar span {
          position: absolute;
          height: 60%;
          top: 20%;
    
          display: block;
    
          -webkit-border-radius: 16px;
          -moz-border-radius: 16px;
          border-radius: 16px;
    }
    
    #seekbar.playhead {
         z-index: 1011;
         height: 14px;
         width: 14px;
         border: 1px outset #c9cbce;
         position: absolute;
         left: -8px; /* adjust center of playhead over start of range */
         display: block;
         padding: 0;
         margin: 0;
    
         background: #c9cbce; /* Old browsers */
         background: -moz-radial-gradient(circle, #4591ce 0%, #3080c2 40%, #c9cbce 45%, #dedee1 100%); /* FF3.6+ */
         background: -webkit-radial-gradient(circle, #4591ce 0%, #3080c2 40%, #c9cbce 45%, #dedee1 100%); /* Chrome10+,Safari5.1+ */
         background: -o-radial-gradient(circle, #4591ce 0%, #3080c2 40%, #c9cbce 45%, #dedee1 100%); /* Opera 11.10+ */
         background: -ms-radial-gradient(circle, #4591ce 0%, #3080c2 40%, #c9cbce 45%, #dedee1 100%); /* IE10+ */
         background: radial-gradient(circle, #4591ce 0%, #3080c2 40%, #c9cbce 45%, #dedee1 100%); /* W3C */
         filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#c9cbce', endColorstr='#dedee1',GradientType=0 ); /* IE6-9 */
    
         -webkit-border-radius: 16px;
         -moz-border-radius: 16px;
         border-radius: 16px;
    }
    
    #seekbar.backer {
            z-index: 1004;
            width: 100%;
    
            background: #414142; /* Old browsers */
            background: -moz-linear-gradient(top,  #414142 0%, #343232 100%); /* FF3.6+ */
            background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#414142), color-stop(100%,#343232)); /* Chrome,Safari4+ */
            background: -webkit-linear-gradient(top,  #414142 0%,#343232 100%); /* Chrome10+,Safari5.1+ */
            background: -o-linear-gradient(top,  #414142 0%,#343232 100%); /* Opera 11.10+ */
            background: -ms-linear-gradient(top,  #414142 0%,#343232 100%); /* IE10+ */
            background: linear-gradient(to bottom,  #414142 0%,#343232 100%); /* W3C */
            filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#414142', endColorstr='#343232',GradientType=0 ); /* IE6-9 */
    
    }
    
    #seekbar .buffer {
           z-index: 1005;
           position: absolute;
    
           background: #4b4b4c; /* Old browsers */
           background: -moz-linear-gradient(top,  #4b4b4c 0%, #818184 100%); /* FF3.6+ */
           background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4b4b4c), color-stop(100%,#818184)); /* Chrome,Safari4+ */
           background: -webkit-linear-gradient(top,  #4b4b4c 0%,#818184 100%); /* Chrome10+,Safari5.1+ */
           background: -o-linear-gradient(top,  #4b4b4c 0%,#818184 100%); /* Opera 11.10+ */
           background: -ms-linear-gradient(top,  #4b4b4c 0%,#818184 100%); /* IE10+ */
           background: linear-gradient(to bottom,  #4b4b4c 0%,#818184 100%); /* W3C */
           filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4b4b4c', endColorstr='#818184',GradientType=0 ); /* IE6-9 */
    }
    
    #seekbar .progress {
            z-index: 1010;
            position: absolute;
    
            background: #4591ce; /* Old browsers */
            background: -moz-linear-gradient(top,  #4591ce 0%, #3080c2 100%); /* FF3.6+ */
            background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#4591ce), color-stop(100%,#3080c2)); /* Chrome,Safari4+ */
            background: -webkit-linear-gradient(top,  #4591ce 0%,#3080c2 100%); /* Chrome10+,Safari5.1+ */
            background: -o-linear-gradient(top,  #4591ce 0%,#3080c2 100%); /* Opera 11.10+ */
            background: -ms-linear-gradient(top,  #4591ce 0%,#3080c2 100%); /* IE10+ */
            background: linear-gradient(to bottom,  #4591ce 0%,#3080c2 100%); /* W3C */
            filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#4591ce', endColorstr='#3080c2',GradientType=0 ); /* IE6-9 */
    }
    
  5. 聆聽 AdobePSDK.TimeChangeEvent 並相應地更新搜尋列。

    player.addEventListener(AdobePSDK.PSDKEventType.TIME_CHANGED, onTimeChange);
    
    /**
         * Called when the player's time changes.
         * Update UI to show current time, seekbar playhead position and buffer level.
         */
         function onTimeChange(event)
         {
           if (!seekBar.isSeeking) {
           var time = event.time;
           var range = player.playbackRange;
           seekBar.updatePlayhead(time, range);
           updateDisplayTime(time, range);
    
            var bufferedRange = player.bufferedRange;
            seekBar.updateBufferLevel(bufferedRange.end, range);
          }
    
        }
    

    此範例會建立搜尋列物件來更新搜尋列:

    /**
        * Seekbar object which handles the display of the player progress,
        * playhead, and buffer level.
        */
        seekBar = (function () {
    
        var playheadHalfSize = 8, // must be half width of playhead defined in CSS
            containerElm = null,
            playheadElm = null,
            backerElm = null,
            bufferElm = null,
            progressElm = null,
            currentPos = 0, // [0,1] relative to range
            currentBuffer = 0,// [0,1] relative to range
            listener = null,
            isSeeking = false,
    
             setPositionChangeListener = function (funct) {
                listener = funct;
             },
    
             getSeekBarBounds = function () {
               return backerElm.getBoundingClientRect();
             },
    
             onPositionChange = function (event) {
                 var pos = event.pageX || event.clientX;
                 var bounds = getSeekBarBounds();
                 // normalize position to seek bounds
                 pos -= bounds.left;
                 var percent = pos / (bounds.right - bounds.left);
    
                 // check bounds
                  if (percent > 1) percent = 1;
                  else if (percent < 0) percent = 0;
    
                  currentPos = percent;
                  setPosition(percent);
               },
    
                  updatePlayhead = function (time, range) {
                  if (!isSeeking) {
                  var pos = convertTimeToRelativePosition(time, range);
                  setPosition(pos);
               }
             },
    
                setPosition = function (percent) {
                // adjust to keep playhead graphic inside container on right side
                var bounds = getSeekBarBounds();
                var pos = percent * (bounds.right - bounds.left);
    
                progressElm.style.width = (pos).toString() + "px";
                playheadElm.style.left = (pos-playheadHalfSize).toString() + "px";
    
                currentPos = percent;
                return percent;
    
                },
    
                 updateBufferLevel = function (level, range) {
                 if (!isSeeking) {
                     var position = convertTimeToRelativePosition(level, range);
                     setBufferLevel(position);
                    }
                },
    
                  setBufferLevel = function (percent) {
                     currentBuffer = percent;
                     var bounds = getSeekBarBounds();
                     var pos = percent * (bounds.right - bounds.left);
    
                            bufferElm.style.width = pos.toString() + "px";
                        },
    
                        resetSeekBar = function () {
                           setPosition(currentPos);
                           setBufferLevel(currentBuffer);
                        },
    
                        convertTimeToRelativePosition = function (time, range) {
                           // convert time to a percentage of the duration
                           var position = (time - range.begin) / range.duration;
                           if (position > 1) position = 1;
                           else if (position < 0) position = 0;
                           return position;
                        },
    
                        unattachEvents = function (e) {
                          this.removeEventListener('mousemove', onPositionChange);
                          this.removeEventListener('mouseout', unattachEvents);
                          this.removeEventListener('mouseup', unattachEvents);
    
                            this.addEventListener('mouseover', attachEvents);
                            isSeeking = false;
                        },
    
                        attachEvents = function (e) {
                           this.addEventListener('mousemove', onPositionChange);
                           this.addEventListener('mouseout', unattachEvents);
                           this.addEventListener('mouseup', unattachEvents);
                           isSeeking = true;
                           return false;
                        };
    
                return  {
                    init : function () {
                      containerElm = document.getElementById("seekbar");
                      backerElm = document.getElementById("backer");
                      playheadElm = document.getElementById("playhead");
                      bufferElm = document.getElementById("buffer");
                      progressElm = document.getElementById("progress");
    
                      // client seek via scrubbing
                      containerElm.addEventListener('mousedown', attachEvents);
    
                      // client seek via single click or 'mouseup' after scrubbing
                      containerElm.addEventListener('click', function (e) {
                         if (listener !== null && !player.areControlsDisabledInAd()) {
                            onPositionChange(e);
                            // callback to notify of desired seek position
                            listener.call(this, currentPos);
                            }
                        });
    
                        // end client seek via scrubbing
                        document.addEventListener('mouseup', function (e) {
                            containerElm.removeEventListener('mouseover', attachEvents);
                        });
                    },
    
                   /**
                   * Is the playhead currently being scrubbed.
                   */
                   isSeeking : isSeeking,
    
                   /**
                   * Change the position of the playhead.
                   * @param time - time in seconds to position playhead
                   * @param range - current playback range
                   */
                   updatePlayhead : updatePlayhead,
    
                   /**
                   * Change the position of the buffer range.
                   * @param time - time in seconds to position head of buffer
                   * @param range - current playback range
                   */
                   updateBufferLevel : updateBufferLevel,
    
                   /**
                   * Set listener which is called when the playhead position changes
                   * by the user event. Listener is not called when playhead position
                   * changes via updatePlayhead function.
                   * @param listener - callback function, passed single position argument
                   * representing the playhead position in the range [0,1].
                   */
                   setPositionChangeListener : setPositionChangeListener,
    
                   /**
                   * Readjust position levels if seekbar is resized.
                   * Should be called every time the video window changes size.
                   */
                   readjustSeekBar : resetSeekBar
                };
    
            })();
    

此頁面上的