用js创建audio对象实现网页迷你音乐播放器

675dbfad8d4a4304a0b92553f165381d.png

主要是靠咋没的audio对象,我就不多说废话了,也不会说,直接上代码;

HTML

<!DOCTYPE html>
<html>

	<head>
		<meta http-equiv="content-type" content="text/html; charset=utf-8">
		<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">

		<title>迷你音乐播放器</title>
		<!-- 字体图标库 -->
		<link rel="stylesheet" href="../fonts/css/font-awesome.css">
		<link rel="stylesheet" href="../css/网页迷你音乐播放器.css">
	</head>

	<body>
		<div class="container">
			<div class="bg"></div>
			<div class="bg-mask"></div>
			<div class="player">
				<div class="player-track">
					<div class="album-name">红模仿</div>
					<div class="track-name">周杰伦 - 红模仿</div>
					<div class="track-time">
						<div class="current-time">00:00</div>
						<div class="total-time">03:50</div>
					</div>
					<div class="progress-box">
						<div class="hover-time">00:36</div>
						<div class="progress-bar"></div>
					</div>
				</div>
				<div class="player-content">
					<div class="album-cover">
						<img src="../image/周杰伦 - 红模仿.jpg" alt="" class="active">
					</div>
					<div class="play-controls">
						<div class="control">
							<div class="button play-prev">
								<i class="fa fa-step-backward"></i>
							</div>
						</div>
						<div class="control">
							<div class="button play-pause">
								<i class="fa fa-play"></i>
							</div>
						</div>
						<div class="control">
							<div class="button play-next">
								<i class="fa fa-step-forward"></i>
							</div>
						</div>
						<div class="control">
							<div class="button play-select">
								<label class="SelectYse"></label>
							</div>
						</div>
					</div>
					<div class="play-controlsTwo">
						<label>
							<input type="checkbox" hidden>
							<span></span>
							<i class="indicator"></i>
						</label>
					</div>
				</div>
			</div>
		</div>
		<script src="../javascript/jquery-3.6.0.min.js"></script>
		<script src="../javascript/网页迷你音乐播放器.js"></script>
	</body>
</html>

 CSS

* {
	/* 初始化 */
	margin: 0;
	padding: 0;
}

body {
	/* 100%窗口高度 */
	height: 100vh;
	/* 弹性布局 居中显示 */
	display: flex;
	justify-content: center;
	align-items: center;
}

.container {
	width: 430px;
	min-height: 100px;
}

/* 模糊背景图 */
.bg {
	/* 固定定位 */
	position: fixed;
	top: -40px;
	right: -40px;
	bottom: -40px;
	left: -40px;
	background: url('../image/周杰伦 - 红模仿.jpg') no-repeat;
	background-size: cover;
	background-position: center;
	/* 模糊滤镜 */
	filter: blur(40px);
	z-index: 1;
}

/* 半透明白色遮罩层 */
.bg-mask {
	position: fixed;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	background: rgba(255, 255, 255, 0.5);
	z-index: 2;
}

.player {
	position: relative;
	z-index: 3;
	width: 100%;
	min-height: 100px;
	height: 100px;
}

/* 歌曲信息轨道区域 */
.player-track {
	position: absolute;
	top: 0;
	right: 15px;
	bottom: 0;
	left: 15px;
	padding: 13px 22px 10px 184px;
	background-color: rgba(255, 255, 255, 0.8);
	border-radius: 15px;
	/* 改变top时的过渡效果 */
	transition: top 0.3s ease;
}

/* 歌曲信息轨道区域活动态 */
.player-track.active {
	/* 上移 */
	top: -95px;
}

.album-name {
	color: #333;
	font-size: 17px;
	font-weight: bold;
	overflow: hidden;
	white-space: nowrap;
	text-overflow: ellipsis;
}

.track-name {
	color: #888;
	font-size: 13px;
	margin: 3px 0 12px 0;
}

.track-time {
	height: 12px;
	line-height: 12px;
	margin-bottom: 4px;
	overflow: hidden;
}

.current-time,
.total-time {
	color: #ff668f;
	font-size: 11px;
	transition: 0.3s ease;
}

.current-time {
	float: left;
}

.total-time {
	float: right;
}

/* 播放进度区域 */
.progress-box {
	position: relative;
	height: 4px;
	transition: height 0.3s ease;
	background-color: #ead2d7;
	border-radius: 4px;
	cursor: pointer;
}

.progress-box:hover {
	height: 8px;
	border-radius: 8px;
}

/* 悬停进度条显示时间 */
.hover-time {
	position: absolute;
	top: -30px;
	background-color: rgba(0, 0, 0, 0.8);
	color: #FFFFFF;
	font-size: 12px;
	padding: 5px 6px;
	border-radius: 4px;
	display: none;
}

/* 已播放的进度条颜色 */
.progress-bar {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	left: 0;
	background-color: #fd6d94;
	border-radius: 4px;
	z-index: 1;
	width: 0;
	/* 改变width时的过渡效果 */
	transition: width 0.2s ease;
}

.player-content {
	position: relative;
	min-height: 100px;
	height: 100%;
	transition: height 0.3s ease;
	background-color: #FFFFFF;
	border-radius: 15px;
	z-index: 2;
	box-shadow: 0 30px 80px #656565;
}

/* 封面 */
.album-cover {
	width: 115px;
	height: 115px;
	border-radius: 50%;
	position: absolute;
	top: -40px;
	left: 40px;
	box-shadow: 0 0 0 10px #FFFFFF;
	overflow: hidden;
	transition: 0.3s ease;
}

/* 唱片中间的小圆点 */
.album-cover::before {
	content: "";
	width: 20px;
	height: 20px;
	background-color: #d6dee6;
	position: absolute;
	top: 50%;
	right: 0;
	bottom: 0;
	left: 0;
	border-radius: 50%;
	margin: -10px auto auto auto;
	box-shadow: inset 0 0 0 2px #FFFFFF;
	z-index: 1;
}

/* 封面活动态 */
.album-cover.active {
	top: -60px;
	box-shadow: 0 0 0 4px #fff7f7,
		0 30px 50px -15px #afb7c1;
}

.album-cover img {
	display: block;
	width: 100%;
	height: 0%;
	object-fit: cover;
	opacity: 0;
}

.album-cover img.active {
	height: 100%;
	opacity: 1;
}

/* 播放时封面旋转 */
.album-cover.active img.active {
	/* 执行动画:动画名 时长 线性的 无限次播放 */
	animation: rotateAlbumCover 5s linear infinite;
}

/* 控制区 */
.play-controls {
	width: 255px;
	height: 100px;
	float: right;
	overflow: hidden;
	display: flex;
	align-items: center;
	padding-right: 2px;
}

.play-controlsTwo {
	width: 100%;
	height: 58px;
	position: absolute;
	bottom: 0px;
	z-index: -1;
	display: none;
	justify-content: center;
	border-radius: 15px;
	overflow: hidden;
	box-sizing: border-box;
	padding: 0px 9px 9px 9px;
}

.control {
	flex: 1;
}

.control .button {
	width: 54px;
	height: 75px;
	display: flex;
	justify-content: center;
	align-items: center;
	background-color: #FFFFFF;
	border-radius: 6px;
	cursor: pointer;
	transition: 0.2s ease;
}

.control .button i {
	color: #d6dee6;
	font-size: 30px;
	transition: 0.2s ease;
}

.control .button:hover {
	background-color: #d6d6de;
}

.control .button:hover i {
	color: #FFFFFF;
}

.button>label {
	position: relative;
	width: 35px;
	height: 5px;
	cursor: pointer;
	display: block;
	border-radius: 2.5px;
	background-color: #d6dee6;
}

.button>label::before,
.button>label::after {
	width: 35px;
	height: 5px;
	display: block;
	z-index: 1;
	cursor: pointer;
	background-color: #d6dee6;
	border-radius: 2.5px;
	content: "";
	position: absolute;
	left: 0;
}

.button>label::before {
	top: -10px;
}

.button>label::after {
	top: 10px;
}

.control>.button:hover>.SelectYse,
.control>.button:hover>label::before,
.control>.button:hover>label::after {
	background-color: #FFFFFF;
}

.button>.SelectYse::before,
.SelectYse::after {
	transition: top 0.5s;
}

.button>.SelectNo {
	background: transparent;
}

.button>.SelectNo::before,
.button>.SelectNo::after {
	transition: transform 0.5s;
}

.button>.SelectNo::before {
	top: 0px;
	transform: rotate(-45deg);
}

.button>.SelectNo::after {
	top: 0px;
	transform: rotate(45deg);
}

.play-controlsTwo>label {
	/* 相对定位 */
	position: relative;
	margin: 5px 0;
	cursor: pointer;
}

.play-controlsTwo>label:before {
	content: "播放本地歌曲";
	position: absolute;
	top: 0px;
	left: -165px;
	width: 165px;
	text-align: center;
	font-weight: bold;
	line-height: 42px;
	font-size: 24px;
}

.play-controlsTwo>label::after {
	content: "播放动漫歌曲";
	position: absolute;
	top: 0px;
	right: -166px;
	width: 165px;
	text-align: center;
	font-weight: bold;
	line-height: 42px;
	font-size: 24px;
}

.play-controlsTwo>label>span {
	position: relative;
	display: block;
	width: 80px;
	height: 40px;
	background-color: #FFFFFF;
	border-radius: 40px;
	/* 内阴影 */
	box-shadow: inset 0 2px 15px rgba(0, 0, 0, 0.2),
		inset 0 2px 2px rgba(0, 0, 0, 0.2),
		inset 0 -1px 1px rgba(0, 0, 0, 0.2);
}

.play-controlsTwo>label>.indicator {
	position: absolute;
	left: 0;
	top: 0;
	width: 40px;
	height: 40px;
	background: linear-gradient(to bottom, #FFFFFF, #eff1f2);
	border-radius: 50%;
	box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5),
		inset 0 1px 1px rgba(255, 255, 255, 0.1);
	transform: scale(0.9);
	transition: 0.5s;
}

.play-controlsTwo>label>input:checked~.indicator {
	left: 40px;
}

.play-controlsTwo>label>input:checked~span {
	background-color: #d6dee6;
}


/* 定义动画 */
@keyframes rotateAlbumCover {
	0% {
		transform: rotateZ(0);
	}

	100% {
		transform: rotateZ(360deg);
	}
}

JavaScript

// 要操作的元素
let play_pause = document.querySelector('.play-pause'),
	player_track = document.querySelector('.player-track'),
	album_cover = document.querySelector('.album-cover'),
	bg = document.querySelector('.bg'),
	album_name = document.querySelector('.album-name'),
	track_name = document.querySelector('.track-name'),
	track_time = document.querySelector('.track-time'),
	current_time = document.querySelector('.current-time'),
	total_time = document.querySelector('.total-time'),
	progress_box = document.querySelector('.progress-box'),
	hover_time = document.querySelector('.hover-time'),
	progress_bar = document.querySelector('.progress-bar'),
	player_content = document.querySelector('.player-content'),
	play_prev = document.querySelector('.play-prev'),
	play_next = document.querySelector('.play-next'),
	play_select = document.querySelector('.play-select'),
	play_select_label = document.querySelector('.play-select>label'),
	play_controlsTwo = document.querySelector('.play-controlsTwo'),
	play_controlsTwo_input = document.querySelector('.play-controlsTwo>label>input');

// 动漫歌曲播放记录
let comic_name = new Array();
// 歌曲信息数组
let track_names = ['周深 - 大鱼', '徐心愉 - 雾里 (完整女声版)', '萧忆情 - 朝辞白帝城 (Live)', '温亮亮 - 相信我们会创造奇迹', '鞠婧祎 - 红昭愿 (Live)',
	'蒋家驹 - 佛系少年', '周杰伦 - 红模仿', '刘凤瑶 - 感官先生', '周杰伦 - 夜曲', '焦迈奇 - 我的名字', '周杰伦 - 本草纲目'
];

// 定义变量
let progress_t, //鼠标在进度条上悬停的位置
	progress_loc, //鼠标在进度条上悬停的音频位置
	c_m, //悬停音频位置(分钟)
	ct_minutes, //悬停播放位置(分)
	ct_seconds, //悬停播放位置(秒)
	cur_minutes, //当前播放时间(分)
	cur_seconds, //当前播放时间(秒)
	dur_minutes, //音频总时长(分)
	dur_seconds, //音频总时长(秒)
	play_progress, //播放进度
	State = false, //播放状态
	labelInput = false, //播放哪种歌曲
	jilushu = 0; //记录动漫记录中的上下首

// 初始化歌曲下标
const array = new Uint32Array(1);
maxUint = 0xffffffff //maxUint为最大的可能值
const randomNum = crypto.getRandomValues(array)[0] / maxUint;
let cur_index = Math.floor((4 - 0 + 1) * randomNum + 0) - 1;

// 初始化
function initPlayer() {
	audio = new Audio(); //创建音频对象
	audio.loop = false; //不循环播放
	selectTrack(0);
	// 绑定播放暂停按钮的点击事件
	play_pause.addEventListener('click', playPause);
	// 进度条鼠标移动事件
	progress_box.addEventListener('mousemove', function(e) {
		showHover(e);
	});
	// 进度条鼠标离开事件
	progress_box.addEventListener('mouseout', hideHover);
	// 进度条点击事件
	progress_box.addEventListener('click', playFromClickedPos);
	// 音频播放位置改变事件
	audio.addEventListener('timeupdate', updateCurTime);
	// 上一首按钮点击事件
	play_prev.addEventListener('click', function() {
		selectTrack(-1);
	});
	// 下一首按钮点击事件
	play_next.addEventListener('click', function() {
		selectTrack(1);
	});
	play_select.addEventListener('click', UIadjustment);
	play_controlsTwo_input.addEventListener('change', networkingANDswitch);
}

//判断设备是否联网,动漫歌曲开关是否打开
function networkingANDswitch() {
	if (this.checked === true) {
		if (navigator.onLine) { //正常工作
			labelInput = true;
		} else { //执行离线状态时的任务
			this.checked = false;
			alert('你的设备未联网');
		}
	} else {
		labelInput = false;
	}
	if (audio.currentTime == 0 && audio.paused === true)
		selectTrack(1);
}

//单击菜单时调整界面
function UIadjustment() {
	if (play_select_label.className == 'SelectYse') {
		play_select_label.classList.remove('SelectYse');
		play_select_label.classList.add('SelectNo');
		player_content.style.height = '158%';
		setTimeout(function() {
			play_controlsTwo.style.display = 'flex';
		}, 300);
	} else {
		play_select_label.classList.remove('SelectNo');
		play_select_label.classList.add('SelectYse');
		play_controlsTwo.style.display = 'none';
		player_content.style.height = '100%';
	}
}

// 播放暂停
function playPause() {
	setTimeout(function() {
		if (audio.paused) {
			player_track.classList.add('active');
			play_pause.querySelector('.fa').classList = 'fa fa-pause';
			album_cover.classList.add('active');
			audio.play();
			State = true;
		} else {
			player_track.classList.remove('active');
			play_pause.querySelector('.fa').classList = 'fa fa-play';
			album_cover.classList.remove('active');
			audio.pause();
			State = false;
		}
	}, 100);
}

// 显示悬停播放位置弹层
function showHover(e) {
	// 计算鼠标在进度条上的悬停位置(当前鼠标的X坐标-进度条在窗口中的left位置)
	progress_t = e.clientX - progress_box.getBoundingClientRect().left;
	// 计算鼠标在进度条上悬停时的音频位置
	// audio.duration 音频总时长
	progress_loc = audio.duration * (progress_t / progress_box.getBoundingClientRect().width);
	// 将悬停音频位置转为分钟
	c_m = progress_loc / 60;
	ct_minutes = Math.floor(c_m); //分
	ct_seconds = Math.floor(progress_loc - ct_minutes * 60); //秒
	if (ct_minutes < 10) {
		ct_minutes = '0' + ct_minutes;
	}
	if (ct_seconds < 10) {
		ct_seconds = '0' + ct_seconds;
	}
	if (isNaN(ct_minutes) || isNaN(ct_seconds)) {
		hover_time.innerText = '--:--';
	} else {
		hover_time.innerText = ct_minutes + ':' + ct_seconds;
	}
	// 设置悬停播放位置弹层的位置并显示
	hover_time.style.left = progress_t + 'px';
	hover_time.style.marginLeft = '-20px';
	hover_time.style.display = 'block';
}

// 隐藏悬停播放位置弹层
function hideHover() {
	hover_time.innerText = '00:00';
	hover_time.style.left = '0px';
	hover_time.style.marginLeft = '0px';
	hover_time.style.display = 'none';
}

// 从点击的位置开始播放
function playFromClickedPos() {
	// 设置当前播放时间
	audio.currentTime = progress_loc;
	// 设置进度条宽度
	progress_bar.style.width = progress_t + 'px';
	// 隐藏悬停播放位置弹层
	hideHover();
}

// 改变当前播放时间
function updateCurTime() {
	// 当前播放时间(分)
	cur_minutes = Math.floor(audio.currentTime / 60);
	// 当前播放时间(秒)
	cur_seconds = Math.floor(audio.currentTime - cur_minutes * 60);
	// 音频总时长(分)
	dur_minutes = Math.floor(audio.duration / 60);
	// 音频总时长(秒)
	dur_seconds = Math.floor(audio.duration - dur_minutes * 60);
	// 计算播放进度
	play_progress = audio.currentTime / audio.duration * 100;
	cur_minutes = cur_minutes < 10 ? '0' + cur_minutes : cur_minutes;
	cur_seconds = cur_seconds < 10 ? '0' + cur_seconds : cur_seconds;
	dur_minutes = dur_minutes < 10 ? '0' + dur_minutes : dur_minutes;
	dur_seconds = dur_seconds < 10 ? '0' + dur_seconds : dur_seconds;
	// 设置播放时间
	if (isNaN(cur_minutes) || isNaN(cur_seconds)) {
		current_time.innerText = '00:00';
	} else {
		current_time.innerText = cur_minutes + ':' + cur_seconds;
	}
	// 设置总时长
	if (isNaN(dur_minutes) || isNaN(dur_seconds)) {
		total_time.innerText = '00:00';
	} else {
		total_time.innerText = dur_minutes + ':' + dur_seconds;
	}
	// 设置进度条宽度
	progress_bar.style.width = play_progress + '%';
	// 播放完毕
	if (play_progress == 100) {
		//自动播放下一首
		selectTrack(1);
		//恢复样式
		// play_pause.querySelector('.fa').classList='fa fa-play';
		// progress_bar.style.width='0px';
		// current_time.innerText='00:00';
		// player_track.classList.remove('active');
		// album_cover.classList.remove('active');
	}
}

// 切换歌曲(flag: 0=初始, 1=下一首, -1=上一首)
function selectTrack(flag) {
	if (labelInput === false) {
		if (flag == 0 || flag == 1) {
			if (cur_index == (track_names.length - 1)) {
				cur_index = 0;
			} else {
				++cur_index;
			}
		} else {
			if (cur_index == 0) {
				cur_index = (track_names.length - 1);
			} else {
				--cur_index;
			}
		}
		if (cur_index > -1 && cur_index < track_names.length) {
			try {
				if (flag == 0) {
					play_pause.querySelector('.fa').classList = 'fa fa-play';
				} else if (State == true) {
					play_pause.querySelector('.fa').classList = 'fa fa-pause';
				}
				progress_bar.style.width = '0px';
				current_time.innerText = '00:00';
				total_time.innerText = '00:00';
				// 当前专辑名
				let cur_album = track_names[cur_index];
				// 当前歌曲信息(歌手 - 歌名)
				let cur_track_name = track_names[cur_index];
				// 设置音频路径和判断文件是否正常加载
				audio.src = '../mp3/' + cur_album + '.mp3?PC' + new Date().getTime();
				setTimeout(function() {
					if (audio.readyState == 0) {
						audio.src = '../wav/' + cur_album + '.wav?PC' + new Date().getTime();
						setTimeout(function() {
							if (audio.readyState == 0) {
								audio.src = '../flac/' + cur_album + '.flac?PC' + new Date().getTime();
								setTimeout(function() {
									if (audio.readyState == 0) {
										selectTrack(1);
									} else {
										AudioNormal();
									}
								}, 333);
							} else {
								AudioNormal();
							}
						}, 333);
					} else {
						AudioNormal();
					}
				}, 334);
				// audio.onerror=function(){}
				function AudioNormal() {
					// 当切换上一首,下一首时,判断是否播放
					if (flag != 0 && State == true) {
						audio.play();
					}
					// 设置专辑名
					album_name.innerText = cur_album;
					// 设置歌曲信息
					track_name.innerText = cur_track_name;
					// 设置封面
					document.querySelector('img').src = '../image/' + cur_album + '.jpg';
					// 将封面设置为背景大图
					bg.style.backgroundImage = 'url(' + document.querySelector('img').src + ')';
					document.querySelector('img').onerror = function() {
						// 设置封面
						document.querySelector('img').src = '../image/迷你音乐.png';
						// 将封面设置为背景大图
						bg.style.backgroundImage = 'url(' + document.querySelector('img').src + ')';
						throw new Error('图片路径有误');
					}
				}
			} catch (e) {
				console.log('程序抛出异常');
			}
		} else {
			// 切换溢出专辑数组时, 恢复cur_index
			if (flag == 0 || flag == 1) {
				--cur_index;
			} else {
				++cur_index;
			}
		}
	} else {
		if (flag == 0 || flag == 1) {
			if (jilushu >= comic_name.length) {
				$.ajax({
					type: 'GET',
					url: 'https://anime-music.jijidown.com/api/v2/music',
					success: function(msg) {
						audio.src = msg.res.play_url;
						if (State == true) {
							audio.play();
						}
						// 设置专辑名
						album_name.innerText = msg.res.title;
						// 设置歌曲信息
						track_name.innerText = msg.res.title;
						let comic_names = {
							title: msg.res.title,
							url: msg.res.play_url
						};
						comic_name.push(comic_names);
						jilushu = comic_name.length;
					}
				});
			} else {
				audio.src = comic_name[jilushu].url;
				if (State == true) {
					audio.play();
				}
				// // 设置专辑名
				album_name.innerText = comic_name[jilushu].title;
				// // 设置歌曲信息
				track_name.innerText = comic_name[jilushu].title;
				jilushu += 1;
			}
		} else {
			if (jilushu - 2 >= 0) {
				audio.src = comic_name[jilushu - 2].url;
				if (State == true) {
					audio.play();
					player_track.classList.add('active');
					album_cover.classList.add('active');
				}
				// // 设置专辑名
				album_name.innerText = comic_name[jilushu - 2].title;
				// // 设置歌曲信息
				track_name.innerText = comic_name[jilushu - 2].title;
				jilushu -= 1;
			}
		}
		document.querySelector('img').src = '../image/迷你音乐.png';
		bg.style.backgroundImage = 'url(../image/迷你音乐.png)';
	}
}

// 初始化播放器
initPlayer();

百度网盘领取完整资源

链接:https://pan.baidu.com/s/1JN8zQjwmk3bjpjgDazRo7A 

提取码:q3m0

注:代码来源各大平台,我只是修改了代码,原作者已忘记,gitee平台上误打误撞下载到的。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

知勤者笔记

给点吧,没动力了!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值