亚伦影音工作室 发表于 2025-1-18 21:17

播放器

本帖最后由 亚伦影音工作室 于 2025-2-3 21:16 编辑 <br /><br /><style>
#papa{width: 1000px; height: 580px;margin: 10px -180px ;position: relative;overflow: hidden;background:#880;
}
.green-audio-player {
width: 400px;
min-width: 300px;
height: 56px;
box-shadow: 0 4px 16px 0 rgba(0, 0, 0, 0.07);
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 24px;
padding-right: 24px;
border-radius: 4px;
user-select: none;
margin: 550px auto;
background-color: #ccc;

}
.green-audio-player .play-pause-btn {
display: none;
cursor: pointer;
}

.green-audio-player .slider {
flex-grow: 1;
background-color: #D8D8D8;
cursor: pointer;
position: relative;
}
.green-audio-player .slider .progress {
background-color: #44BFA3;
border-radius: inherit;
position: absolute;
pointer-events: none;
}
.green-audio-player .slider .progress .pin {
height: 16px;
width: 16px;
border-radius: 8px;
background-color: #44BFA3;
position: absolute;
pointer-events: all;
box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.32);
}
.green-audio-player .controls {
font-family: 'Roboto', sans-serif;
font-size: 16px;
line-height: 18px;
color: #fff;
display: flex;
flex-grow: 1;
justify-content: space-between;
align-items: center;
margin-left: 24px;
margin-right: 24px;
}
.green-audio-player .controls .slider {
margin-left: 16px;
margin-right: 16px;
border-radius: 2px;
height: 4px;
}
.green-audio-player .controls .slider .progress {
width: 0;
height: 100%;
}
.green-audio-player .controls .slider .progress .pin {
right: -8px;
top: -6px;
}
.green-audio-player .controls span {
cursor: default;
}
.green-audio-player .volume {
position: relative;
}
.green-audio-player .volume .volume-btn {
cursor: pointer;
}
.green-audio-player .volume .volume-btn.open path {
fill: #fff;
}
.green-audio-player .volume .volume-controls {
width: 30px;
height: 135px;
background-color: #111;
border-radius: 7px;
position: absolute;
left: -3px;
bottom: 52px;
    flex-direction: column;
align-items: center;
display: flex;
}
.green-audio-player .volume .volume-controls.hidden {
display: none;
}
.green-audio-player .volume .volume-controls .slider {
margin-top: 12px;
margin-bottom: 12px;
width: 6px;
border-radius: 3px;
}
.green-audio-player .volume .volume-controls .slider .progress {
bottom: 0;
height: 100%;
width: 6px;
}
.green-audio-player .volume .volume-controls .slider .progress .pin {
left: -5px;
top: -8px;
}
.lrc{
    width: 100%;
    height: 120px; align-items: center;
    overflow: hidden;bottom: 20px;
    display: block;position: absolute;
    margin: 0px ;}
.lrc #ullrc{
width: 100%;
padding: 0;list-style: none;transition: 0.3s all ease;
    margin: 0;}
/*歌词普通样式*/
.lrc #ullrc li{
    height: 70px;
    line-height: 60px;
font-family:华文隶书;
    font-size: 0px;
    color: #000078;
    font-weight: normal;
    transition: .3s all ease;
    list-style-type: none;
    text-align: center;display: block;
    width: 100%;
    margin: 0 auto;}
/*动态歌词样式*/
.lrc #ullrc li.active{
    font-size: 50px;
    color: #ff0000;
text-align: center;text-align: center;color: transparent; background: repeating-linear-gradient(to right, gold, lightgreen, snow, lightgreen, orange) 50%/200px 60px; -webkit-background-clip: text;filter:drop-shadow(#000 1px 0 0)drop-shadow(#000 0 1px 0)drop-shadow(#000 -1px 0 0) drop-shadow(#000 0 -1px0);

</style>

<div id="papa">
<div class="lrc">
      <ul id="ullrc">
         </ul>
      </div>
      
</div>


<div class="green-audio-player">
<div class="play-pause-btn">
    <svg xmlns="http://www.w3.org/2000/svg" width="18" height="24" viewBox="0 0 18 24">
      <path fill="#880000" fill-rule="evenodd" d="M0 0h6v24H0zM12 0h6v24h-6z" class="play-pause-icon" id="playPause"/>
    </svg>
</div>

<div class="controls">
    <span class="current-time">0:00</span>
    <div class="slider" data-direction="horizontal">
      <div class="progress">
      <div class="pin" id="progress-pin" data-method="rewind"></div>
      </div>
    </div>
    <span class="total-time">0:00</span>
</div>

<div class="volume">
    <div class="volume-btn">
      <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
      <path fill="#880000" fill-rule="evenodd" d="M14.667 0v2.747c3.853 1.146 6.666 4.72 6.666 8.946 0 4.227-2.813 7.787-6.666 8.934v2.76C20 22.173 24 17.4 24 11.693 24 5.987 20 1.213 14.667 0zM18 11.693c0-2.36-1.333-4.386-3.333-5.373v10.707c2-.947 3.333-2.987 3.333-5.334zm-18-4v8h5.333L12 22.36V1.027L5.333 7.693H0z" id="speaker"/>
      </svg>
    </div>
    <div class="volume-controls hidden">
      <div class="slider" data-direction="vertical">
      <div class="progress">
          <div class="pin" id="volume-pin" data-method="changeVolume"></div>
      </div>
      </div>
    </div>
</div>

<audio autoplayid="aud">
    <source src="https://aod.cos.tx.xmcdn.com/storages/ff0c-audiofreehighqps/BF/7C/GKwRIaILX3FWABK6GgNWbTp_.m4a" type="audio/mpeg">
</audio>
</div>

<script>
'use strict';

var audioPlayer = document.querySelector('green-audio-player');
var playPause = audioPlayer.querySelector('#playPause');
var playpauseBtn = audioPlayer.querySelector('.play-pause-btn');
var loading = audioPlayer.querySelector('.loading');
var progress = audioPlayer.querySelector('.progress');
var sliders = audioPlayer.querySelectorAll('.slider');
var volumeBtn = audioPlayer.querySelector('.volume-btn');
var volumeControls = audioPlayer.querySelector('.volume-controls');
var volumeProgress = volumeControls.querySelector('.slider .progress');
var player = audioPlayer.querySelector('audio');
var currentTime = audioPlayer.querySelector('.current-time');
var totalTime = audioPlayer.querySelector('.total-time');
var speaker = audioPlayer.querySelector('#speaker');

var draggableClasses = ['pin'];
var currentlyDragged = null;

window.addEventListener('mousedown', function (event) {

if (!isDraggable(event.target)) return false;

currentlyDragged = event.target;
var handleMethod = currentlyDragged.dataset.method;

this.addEventListener('mousemove', window, false);

window.addEventListener('mouseup', function () {
    currentlyDragged = false;
    window.removeEventListener('mousemove', window, false);
}, false);
});

playpauseBtn.addEventListener('click', togglePlay);
player.addEventListener('timeupdate', updateProgress);
player.addEventListener('volumechange', updateVolume);
player.addEventListener('loadedmetadata', function () {
totalTime.textContent = formatTime(player.duration);
});
player.addEventListener('canplay', makePlay);
player.addEventListener('ended', function () {
playPause.attributes.d.value = "M18 12L0 24V0";
player.currentTime = 0;
});

volumeBtn.addEventListener('click', function () {
volumeBtn.classList.toggle('open');
volumeControls.classList.toggle('hidden');
});

window.addEventListener('resize', directionAware);

sliders.forEach(function (slider) {
var pin = slider.querySelector('.pin');
slider.addEventListener('click', window);
});

directionAware();

function isDraggable(el) {
var canDrag = false;
var classes = Array.from(el.classList);
draggableClasses.forEach(function (draggable) {
    if (classes.indexOf(draggable) !== -1) canDrag = true;
});
return canDrag;
}

function inRange(event) {
var rangeBox = getRangeBox(event);
var rect = rangeBox.getBoundingClientRect();
var direction = rangeBox.dataset.direction;
if (direction == 'horizontal') {
    var min = rangeBox.offsetLeft;
    var max = min + rangeBox.offsetWidth;
    if (event.clientX < min || event.clientX > max) return false;
} else {
    var min = rect.top;
    var max = min + rangeBox.offsetHeight;
    if (event.clientY < min || event.clientY > max) return false;
}
return true;
}

function updateProgress() {
var current = player.currentTime;
var percent = current / player.duration * 100;
progress.style.width = percent + '%';

currentTime.textContent = formatTime(current);
}

function updateVolume() {
volumeProgress.style.height = player.volume * 100 + '%';
if (player.volume >= 0.5) {
    speaker.attributes.d.value = 'M14.667 0v2.747c3.853 1.146 6.666 4.72 6.666 8.946 0 4.227-2.813 7.787-6.666 8.934v2.76C20 22.173 24 17.4 24 11.693 24 5.987 20 1.213 14.667 0zM18 11.693c0-2.36-1.333-4.386-3.333-5.373v10.707c2-.947 3.333-2.987 3.333-5.334zm-18-4v8h5.333L12 22.36V1.027L5.333 7.693H0z';
} else if (player.volume < 0.5 && player.volume > 0.05) {
    speaker.attributes.d.value = 'M0 7.667v8h5.333L12 22.333V1L5.333 7.667M17.333 11.373C17.333 9.013 16 6.987 14 6v10.707c2-.947 3.333-2.987 3.333-5.334z';
} else if (player.volume <= 0.05) {
    speaker.attributes.d.value = 'M0 7.667v8h5.333L12 22.333V1L5.333 7.667';
}
}

function getRangeBox(event) {
var rangeBox = event.target;
var el = currentlyDragged;
if (event.type == 'click' && isDraggable(event.target)) {
    rangeBox = event.target.parentElement.parentElement;
}
if (event.type == 'mousemove') {
    rangeBox = el.parentElement.parentElement;
}
return rangeBox;
}

function getCoefficient(event) {
var slider = getRangeBox(event);
var rect = slider.getBoundingClientRect();
var K = 0;
if (slider.dataset.direction == 'horizontal') {

    var offsetX = event.clientX - slider.offsetLeft;
    var width = slider.clientWidth;
    K = offsetX / width;
} else if (slider.dataset.direction == 'vertical') {

    var height = slider.clientHeight;
    var offsetY = event.clientY - rect.top;
    K = 1 - offsetY / height;
}
return K;
}

function rewind(event) {
if (inRange(event)) {
    player.currentTime = player.duration * getCoefficient(event);
}
}

function changeVolume(event) {
if (inRange(event)) {
    player.volume = getCoefficient(event);
}
}

function formatTime(time) {
var min = Math.floor(time / 60);
var sec = Math.floor(time % 60);
return min + ':' + (sec < 10 ? '0' + sec : sec);
}

function togglePlay() {
if (player.paused) {
    playPause.attributes.d.value = "M0 0h6v24H0zM12 0h6v24h-6z";
    player.play();
} else {
    playPause.attributes.d.value = "M18 12L0 24V0";
    player.pause();
}
}

function makePlay() {
playpauseBtn.style.display = 'block';
loading.style.display = 'none';
}

function directionAware() {
if (window.innerHeight < 250) {
    volumeControls.style.bottom = '-54px';
    volumeControls.style.left = '54px';
} else if (audioPlayer.offsetTop < 154) {
    volumeControls.style.bottom = '-164px';
    volumeControls.style.left = '-3px';
} else {
    volumeControls.style.bottom = '52px';
    volumeControls.style.left = '-3px';
}
}
</script>
<script >
var lrc = `你一直在我一直爱
词曲:晓朋
编曲:晓朋
HTML:歌词同步
创意制作;亚伦影音
走在这个迷情的时代
谁不渴望能得到真爱
倾心相遇在爱的花海
相依相守永远不分开
总要经历漫长的等待
爱的玫瑰才为你盛开
一颗真心换一份热爱
不离不弃才能到发白
你一直在我便一直爱
为你守住这爱的情怀
风雨沧桑都不会更改
海枯石烂是我的表白
你一直在我便一直爱
有你天空不再有阴霾
海角天涯爱不会分解
地老天荒爱与你同在
总要经历漫长的等待
爱的玫瑰才为你盛开
一颗真心换一份热爱
不离不弃才能到发白
你一直在我便一直爱
为你守住这爱的情怀
风雨沧桑都不会更改
海枯石烂是我的表白
你一直在我便一直爱
有你天空不再有阴霾
海角天涯爱不会分解
地老天荒爱与你同在
你一直在我便一直爱
有你天空不再有阴霾
海角天涯爱不会分解
地老天荒爱与你同在
海角天涯爱不会分解
地老天荒爱与你同在
`;
function $(id) {
    return document.getElementById(id);
}//这样写以后getid方便
function getLrcArray() {
    var parts = lrc.split("\n");
    for (let index = 0; index < parts.length; index++) {
      parts = getLrcObj(parts);
    }
    return parts;

    function getLrcObj(content) {
      var twoParts = content.split("]");
      var time = twoParts.substr(1);
      var timeParts = time.split(":");
      var seconds = +timeParts;
      var min = +timeParts;
      seconds = min * 60 + seconds;
      var words = twoParts;
      return{
            seconds: seconds,
            words: words,
      };
    }
}
var lrcArray = getLrcArray();
function inputLrc() {
    for (let index = 0; index < lrcArray.length; index++) {
      var li = document.createElement("li");
      li.innerText = lrcArray.words;
      $("ullrc").appendChild(li);
    }
}
inputLrc();
function setPosition() {
    var index = getLrcIndex();
    if (index == -1) {
      return;
    }
   var lrc_li_height = 70, lrc_ul_height = 60;/*动态歌词显示的位置:250:第三行变色增大。160:在第二行变化。50:在第一行变化 */
    var top = index * lrc_li_height + lrc_li_height / 2 - lrc_ul_height / 2;
    if (top < 0) {
      top = 0;
    }
    $("ullrc").style.marginTop = -top + "px";
    var activeLi = $("ullrc").querySelector(".active");
    if(activeLi){
      activeLi.classList.remove("active");
    }
    $("ullrc").children.classList.add("active");
}
var turn = 0;
function getLrcIndex(){
    var time = $("aud").currentTime + turn;
    for (var index = 0; index < lrcArray.length; index++) {
      if (lrcArray.seconds > time) {
            return index - 1;
      }
    }
}
$("aud").ontimeupdate = setPosition;
</script >

红影 发表于 2025-1-18 21:38

是的,挺漂亮的。的确进度没法拖动{:4_204:}

秋思梦景 发表于 2025-1-19 08:39

问候老师好!精美播放器佳作,精心制作分享。为您点赞!{:5_116:}{:4_187:}

马黑黑 发表于 2025-1-20 12:07

关于定位播放器的问题:

(一)需要给 .green-audio-player 选择器加入 position: absolute; 属性设置,这样即可随意定位到帖子任意位置;
(二)由于HTML代码流中,class="green-audio-player" 的标签出现在前面,层级关系上它被后面的元素”覆盖“,故而其上的按钮点击失效,需要提升 z-index 属性值,同样再CSS中设置,在 .green-audio-player 选择其中加入 z-index: 200; 即可。

亚伦影音工作室 发表于 2025-1-20 22:20

马黑黑 发表于 2025-1-20 12:07
关于定位播放器的问题:

(一)需要给 .green-audio-player 选择器加入 position: absolute; 属性设置, ...

这些东西都加上进度条就失效了!

马黑黑 发表于 2025-1-20 22:35

亚伦影音工作室 发表于 2025-1-20 22:20
这些东西都加上进度条就失效了!

这些其实就是HTML元素的布局问题,可以再细细研究一下

亚伦影音工作室 发表于 2025-1-21 08:09

本帖最后由 亚伦影音工作室 于 2025-1-21 08:36 编辑

马黑黑 发表于 2025-1-20 22:35
这些其实就是HTML元素的布局问题,可以再细细研究一下
细细看了,也看不出来毛病!人家的代码我不想去改,只是加了歌词,别的没动,现在我没加定位代码一样可以用,用定位反而进度条不灵了!
用margin: 644px auto;来定位还可以。

老师你能不能在这个基础上做个横向音量条!

马黑黑 发表于 2025-1-21 19:53

亚伦影音工作室 发表于 2025-1-21 08:09
细细看了,也看不出来毛病!人家的代码我不想去改,只是加了歌词,别的没动,现在我没加定位代码一样可以 ...

如果不想复杂的定位,那么:

方法一:可以这样处理:帖子中设计一个div标签,用它来包裹你所引入的播放器,然后你仅需要控制那个div的定位;

方法二:可以使用 transform: translate(x,y) 直接控制播放器的定位(这个方法要比margin好)。

至于音量条,横向纵向的其实是简单的,只是目前没有兴趣做,你可以自行研究一下,但不建议再这个播放器基础上做,它的实现方式过于臃肿。

亚伦影音工作室 发表于 2025-1-21 20:22

马黑黑 发表于 2025-1-21 19:53
如果不想复杂的定位,那么:

方法一:可以这样处理:帖子中设计一个div标签,用它来包裹你所引入的播 ...



测试用了很多方法,包括你说的我都试过了,可以加上但这个进度条加上失灵了!就像用了魔法,不再玩他了,伤脑!
不过还是谢谢老师的指导!
页: [1]
查看完整版本: 播放器