热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用JavaScript创建音乐播放器的案例详解

英文|https:www.geeksforgeeks.orgcreate-a-music-player-using-javascript?refleftbar-rightbar翻译

英文 | https://www.geeksforgeeks.org/create-a-music-player-using-Javascript/?ref=leftbar-rightbar

翻译 | web前端开发(ID:web_qdkf)

随着越来越多的用户使用流媒体,在线媒体播放器已成为消费在Internet上必不可少的媒介。音乐播放器允许人们在任何浏览器中欣赏音乐,并支持离线音乐播放器的许多功能。

我们将创建一个用户界面干净的音乐播放器,可用于在浏览器中播放音乐。我们还将实现搜索和音量控制等功能。HTML在HTMLMediaElement接口中有几种方法,可用于播放音频文件并控制其播放,而无需使用任何其他库。

我们首先将创建HTML,使用HTML布局定义播放器的结构,再通过使用CSS样式使其外观看起来更美观,然后使用Javascript编写它的所有功能,以及编写播放器逻辑。

HTML布局
HTML布局定义了将在页面上显示的元素结构。播放器可以分为以下几部分:

  • 详细信息部分:此部分显示正在播放的当前曲目的详细信息。它包括曲目编号,曲目专辑,曲目名称和曲目艺术家。

  • 按钮部分:此部分显示用于控制曲目播放的按钮。它包括播放/暂停按钮,上上一曲和下一曲的曲目按钮。它们将使用onclick()方法来实现,该方法调用Javascript文件中定义的特定函数。

  • 滑块部分:此部分包含可用于控制播放和音量的搜寻滑块和音量滑块。

我们将使用FontAwesome图标来获取页面上使用的所有按钮的图标。文件中还将链接我们稍后将编写的自定义的CSS和Javascript。

HTML代码如下:

 

PLAYING x OF y
Track Name
Track Artist
00:00
00:00

CSS样式
使用CSS我们可以设置不同部分的样式,以使其在视觉上更具吸引力:

  • flex布局用于排列播放器的各种元素,并将它们与页面的中间对齐。

  • 轨道艺术图像具有固定的尺寸,并使用border-radius属性进行了舍入。

  • 这两个滑块已经通过使用外观属性从其默认外观进行了修改。更改高度和背景以适合配色方案。它们还具有轻微的透明度,可以使用transition属性平滑过渡到完全不透明。

  • 所有播放控件的cursor属性均已设置,以便每当鼠标悬停在其上时,它将变为指针。

body {  background-color: lightgreen; /* Smoothly transition the background color */ transition: background-color .5s; }
/* Using flex with the column direction to align items in a vertical direction */.player { height: 95vh; display: flex; align-items: center; flex-direction: column; justify-content: center; }
.details { display: flex; align-items: center; flex-direction: column; justify-content: center; margin-top: 25px; }
.track-art { margin: 25px; height: 250px; width: 250px; background-image: URL( "https://source.unsplash.com/Qrspubmx6kE/640x360"); background-size: cover; background-position: center; border-radius: 15%; }
/* Changing the font sizes to suitable ones */.now-playing { font-size: 1rem; }
.track-name { font-size: 3rem; }
.track-artist { font-size: 1.5rem; }
/* Using flex with the row direction to align items in a horizontal direction */.buttons { display: flex; flex-direction: row; align-items: center; }
.playpause-track, .prev-track, .next-track { padding: 25px; opacity: 0.8; /* Smoothly transition the opacity */ transition: opacity .2s; }
/* Change the opacity when mouse is hovered */.playpause-track:hover, .prev-track:hover, .next-track:hover { opacity: 1.0; }
/* Define the slider width so that it scales properly */.slider_container { width: 75%; max-width: 400px; display: flex; justify-content: center; align-items: center; }
/* Modify the appearance of the slider */.seek_slider, .volume_slider { -webkit-appearance: none; -moz-appearance: none; appearance: none; height: 5px; background: black; opacity: 0.7; -webkit-transition: .2s; transition: opacity .2s; }
/* Modify the appearance of the slider thumb */.seek_slider::-webkit-slider-thumb, .volume_slider::-webkit-slider-thumb { -webkit-appearance: none; -moz-appearance: none; appearance: none; width: 15px; height: 15px; background: white; cursor: pointer; border-radius: 50%; }
/* Change the opacity when mouse is hovered */.seek_slider:hover, .volume_slider:hover { opacity: 1.0; }
.seek_slider { width: 60%; }
.volume_slider { width: 30%; }
.current-time, .total-duration { padding: 10px; }
i.fa-volume-down, i.fa-volume-up { padding: 10px; }
/* Change the mouse cursor to a pointer when hovered over */i.fa-play-circle, i.fa-pause-circle, i.fa-step-forward, i.fa-step-backward { cursor: pointer; }

HTML布局和CSS样式的结果将显示以下外观:

播放器的Javascript逻辑:

播放器的逻辑在Javascript文件中定义。有几种功能可以共同处理播放器的所有功能。

步骤1:定义所有变量并访问HTML元素
首先使用querySelector()方法选择HTML布局中要动态更改的必需元素。然后为它们分配变量名,以便可以对其进行访问和修改。还定义了将在整个程序中访问的其他变量。

// Select all the elements in the HTML page
// and assign them to a variable
let now_playing = document.querySelector(".now-playing");
let track_art = document.querySelector(".track-art");
let track_name = document.querySelector(".track-name");
let track_artist = document.querySelector(".track-artist"); let playpause_btn = document.querySelector(".playpause-track");
let next_btn = document.querySelector(".next-track");
let prev_btn = document.querySelector(".prev-track"); let seek_slider = document.querySelector(".seek_slider");
let volume_slider = document.querySelector(".volume_slider");
let curr_time = document.querySelector(".current-time");
let total_duration = document.querySelector(".total-duration"); // Specify globally used values
let track_index = 0;
let isPlaying = false;
let updateTimer; // Create the audio element for the player
let curr_track = document.createElement('audio'); // Define the list of tracks that have to be played
let track_list = [ { name: "Night Owl", artist: "Broke For Free", image: "Image URL", path: "Night_Owl.mp3"}, { name: "Enthusiast", artist: "Tours", image: "Image URL", path: "Enthusiast.mp3"}, { name: "Shipping Lanes", artist: "Chad Crouch", image: "Image URL", path: "Shipping_Lanes.mp3", },
];

步骤2:从轨道列表中加载新轨道在轨道列表中,
所有必须播放的轨道都被定义为对象。这些对象包含名称,艺术家,图像和轨道路径等属性。然后可以使用其轨道索引访问每个轨道。

要加载曲目,loadTrack()定义了一个函数,该函数处理以下事情:

  • 重置前一曲
    目的所有值将创建一个resetValues()函数,该函数在将新曲目开始之前,将持续时间值和滑块重置为初始值。这样可以防止在加载新轨道时搜索滑块跳动。

  • 加载轨道
    使用其src属性为音频元素分配一个新的源。可以给它来自文件系统或URL的任何路径。然后在音频元素上使用load()方法来准备轨道。

  • 更新要显示
    的轨迹图从阵列中获取轨迹图,并在backgroundImage属性的帮助下进行分配。

  • 更新要显示
    的轨道详细信息从数组中获取轨道详细信息,并在textContent属性的帮助下进行分配。

  • 将事件侦听器添加到轨道
    media元素上添加了两个事件侦听器,第一个用于更新当前搜索位置,第二个侦听器用于在当前轨道结束时加载下一个轨道。

  • 设置随机的彩色背景
    通过对使用的红色,绿色和蓝色值进行随机化并将其设置为颜色来生成彩色背景。通过使用上的transition属性来为效果设置动画background-color。

function loadTrack(track_index) {  // Clear the previous seek timer clearInterval(updateTimer); resetValues(); // Load a new track curr_track.src = track_list[track_index].path; curr_track.load(); // Update details of the track track_art.style.backgroundImage = "url(" + track_list[track_index].image + ")"; track_name.textCOntent= track_list[track_index].name; track_artist.textCOntent= track_list[track_index].artist; now_playing.textCOntent= "PLAYING " + (track_index + 1) + " OF " + track_list.length; // Set an interval of 1000 milliseconds // for updating the seek slider updateTimer = setInterval(seekUpdate, 1000); // Move to the next track if the current finishes playing // using the 'ended' event curr_track.addEventListener("ended", nextTrack); // Apply a random background color random_bg_color(); }
function random_bg_color() { // Get a random number between 64 to 256 // (for getting lighter colors) let red = Math.floor(Math.random() * 256) + 64; let green = Math.floor(Math.random() * 256) + 64; let blue = Math.floor(Math.random() * 256) + 64; // Construct a color withe the given values let bgColor = "rgb(" + red + ", " + green + ", " + blue + ")"; // Set the background to the new color document.body.style.background = bgColor; }
// Functiom to reset all values to their default function resetValues() { curr_time.textCOntent= "00:00"; total_duration.textCOntent= "00:00"; seek_slider.value = 0; }

步骤3:配置播放器按钮
函数playTrack()句柄当前加载的曲目的播放。所述play()的HTMLMediaElement API的方法用于此功能。按钮的图标也变为暂停图标。这是通过使用FontAwesome库中的图标之一并使用innerHTML插入它来完成的。

一个函数pauseTrack()处理当前加载的曲目的播放。所述pause()的HTMLMediaElement API的方法用于此功能。按钮的图标也变回播放图标。这是通过使用FontAwesome库中的图标之一并使用innerHTML插入它来完成的。

根据轨道当前是否正在播放来调用这两个功能。playpause()函数处理轨道的实际播放/暂停控制。

函数prevTrack()处理上一曲目的加载并向后移动索引。当索引到达第一个曲目时,索引会重置为最后一个曲目。上面定义的loadTrack()方法用于加载新轨道。

类似地,一个函数nextTrack()处理下一个曲目的加载并向前移动索引。当索引到达最后一个音轨时,索引会重置为第一个音轨。上面定义的loadTrack()方法用于加载新轨道。

function playpauseTrack() {  // Switch between playing and pausing // depending on the current state if (!isPlaying) playTrack(); else pauseTrack(); }
function playTrack() { // Play the loaded track curr_track.play(); isPlaying = true; // Replace icon with the pause icon playpause_btn.innerHTML = ''; }
function pauseTrack() { // Pause the loaded track curr_track.pause(); isPlaying = false; // Replace icon with the play icon playpause_btn.innerHTML = '';; }
function nextTrack() { // Go back to the first track if the // current one is the last in the track list if (track_index function prevTrack() { // Go back to the last track if the // current one is the first in the track list if (track_index > 0) track_index -= 1; else track_index = track_list.length; // Load and play the new track loadTrack(track_index); playTrack(); }

步骤4:配置滑块部分

我们将设置两个滑块,分别控制搜索滑块和音量滑块。

  • 搜索滑块
    “搜索”滑块通过用轨道的当前时间进行更新来在滑块上显示当前播放位置。创建一个新函数seekUpdate(),以处理相对于轨道当前时间的搜索滑块的更新。搜索滑块的位置是使用value属性计算和设置的。

  • 现在,每次轨道进一步前进时都必须调用此函数。这可以通过安排每秒更新一次来完成。可以使用setInterval()方法(间隔为1000毫秒)来完成此操作。每次加载新曲目时,都会清除此计时器。

  • 此功能还可以处理经过的时间和曲目的总持续时间的更改,该更改在每次触发时都会更新。分钟和秒分别计算并正确格式化以显示。

  • 音量滑块
    音量滑块用于显示曲目的当前音量。创建了一个新函数setVolume(),每当用户对其进行更改时,该函数都会处理音量滑块的设置。

function seekTo() {  // Calculate the seek position by the // percentage of the seek slider // and get the relative duration to the track seekto = curr_track.duration * (seek_slider.value / 100); // Set the current track position to the calculated seek position curr_track.currentTime = seekto; }
function setVolume() { // Set the volume according to the // percentage of the volume slider set curr_track.volume = volume_slider.value / 100; }
function seekUpdate() { let seekPosition = 0; // Check if the current track duration is a legible number if (!isNaN(curr_track.duration)) { seekPosition = curr_track.currentTime * (100 / curr_track.duration); seek_slider.value = seekPosition; // Calculate the time left and the total duration let currentMinutes = Math.floor(curr_track.currentTime / 60); let currentSecOnds= Math.floor(curr_track.currentTime - currentMinutes * 60); let duratiOnMinutes= Math.floor(curr_track.duration / 60); let duratiOnSeconds= Math.floor(curr_track.duration - durationMinutes * 60); // Add a zero to the single digit time values if (currentSeconds <10) { currentSecOnds= "0" + currentSeconds; } if (durationSeconds <10) { duratiOnSeconds= "0" + durationSeconds; } if (currentMinutes <10) { currentMinutes = "0" + currentMinutes; } if (durationMinutes <10) { duratiOnMinutes= "0" + durationMinutes; } // Display the updated duration curr_time.textCOntent= currentMinutes + ":" + currentSeconds; total_duration.textCOntent= durationMinutes + ":" + durationSeconds; } }

步骤5:启动播放器

通过调用loadTrack()函数加载第一首曲目。这将从轨道列表中加载第一个轨道,并更新轨道的所有详细信息。然后,用户可以使用“播放”按钮开始播放曲目。上一个和下一个曲目按钮将分别加载上一个和下一个曲目并开始播放。

曲目播放完毕后,将自动加载下一个曲目。用户可以使用搜索滑块在轨道中搜索位置。也可以使用音量滑块调节音量。

// Load the first track in the tracklist loadTrack(track_index);

最后演示

现在可以在任何浏览器中使用播放器了。可以将新曲目添加到曲目列表,以播放你选择的音乐。

本文完~

视频播放



推荐阅读
  • 本文介绍了pack布局管理器在Perl/Tk中的使用方法及注意事项。通过调用pack()方法,可以控制部件在显示窗口中的位置和大小。同时,本文还提到了在使用pack布局管理器时,应注意将部件分组以便在水平和垂直方向上进行堆放。此外,还介绍了使用Frame部件或Toplevel部件来组织部件在窗口内的方法。最后,本文强调了在使用pack布局管理器时,应避免在中间切换到grid布局管理器,以免造成混乱。 ... [详细]
  • 推荐系统遇上深度学习(十七)详解推荐系统中的常用评测指标
    原创:石晓文小小挖掘机2018-06-18笔者是一个痴迷于挖掘数据中的价值的学习人,希望在平日的工作学习中,挖掘数据的价值, ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • EPICS Archiver Appliance存储waveform记录的尝试及资源需求分析
    本文介绍了EPICS Archiver Appliance存储waveform记录的尝试过程,并分析了其所需的资源容量。通过解决错误提示和调整内存大小,成功存储了波形数据。然后,讨论了储存环逐束团信号的意义,以及通过记录多圈的束团信号进行参数分析的可能性。波形数据的存储需求巨大,每天需要近250G,一年需要90T。然而,储存环逐束团信号具有重要意义,可以揭示出每个束团的纵向振荡频率和模式。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 目录实现效果:实现环境实现方法一:基本思路主要代码JavaScript代码总结方法二主要代码总结方法三基本思路主要代码JavaScriptHTML总结实 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • javascript  – 概述在Firefox上无法正常工作
    我试图提出一些自定义大纲,以达到一些Web可访问性建议.但我不能用Firefox制作.这就是它在Chrome上的外观:而那个图标实际上是一个锚点.在Firefox上,它只概述了整个 ... [详细]
  • 本文介绍了PhysioNet网站提供的生理信号处理工具箱WFDB Toolbox for Matlab的安装和使用方法。通过下载并添加到Matlab路径中或直接在Matlab中输入相关内容,即可完成安装。该工具箱提供了一系列函数,可以方便地处理生理信号数据。详细的安装和使用方法可以参考本文内容。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • FeatureRequestIsyourfeaturerequestrelatedtoaproblem?Please ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 使用圣杯布局模式实现网站首页的内容布局
    本文介绍了使用圣杯布局模式实现网站首页的内容布局的方法,包括HTML部分代码和实例。同时还提供了公司新闻、最新产品、关于我们、联系我们等页面的布局示例。商品展示区包括了车里子和农家生态土鸡蛋等产品的价格信息。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
author-avatar
善良历史代言人_749
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有