数字媒体技术综合实训报告

1、实训目的

1)掌握 PS 工具的使用
2)掌握 AI 工具的使用
3)掌握 PC 端设计规范与技巧
4)运用 PS、AI 完成实战项目音乐盒原型界面的设计

2、实训意义

1)实践环节理论联系实际教学,拓展视野,增加学生对专业感性认识的深度。

2)运用所学知识和技能为后续毕业设计奠定较好的基础。

3)确立学习方向,努力探索学习与就业的结合点,从而发挥学习的主观能动性。

3、实训内容

1)音乐盒静态页面分析实现

以下要通过代码实现一个播放器,用于解析歌曲地址,实现播放、暂停、上一首、下一首等功能。

先放上界面原型图:

WEB音乐盒原型图.png

接下来就是根据原型图搭建 HTML 的整体结构,有木有很简单:

<header></header>
<section class="menu"></section>
<main class="main"></main>
<section class="playpanel"></section>
<section class="playbar"></section>

2)歌单列表的实现

歌单列表使用 table 元素实现,而其上是歌单的详细信息,包括创建者、歌单名称等。

以下是歌单列表的html结构:

<div class="playlist-wrap">
    <table class="playlist-table">
        <thead>
            <th class="order"><div class="ceil">#</div></th>
            <th class="action"><div class="ceil ceil-action">操作</div></th>
            <th><div class="ceil">音乐标题</div></th>
            <th><div class="ceil">歌手</div></th>
            <th><div class="ceil">专辑</div></th>
            <th><div class="ceil">时长</div></th>
        </thead>
        <tbody></tbody>
    </table>
    <div class="table-tips">- 已经没有更多咯 -</div>
</div>

3)歌曲播放功能的实现

浏览器中的音乐播放功能基于 HTMLAudioElement,这是 HTML5 中令人激动的新功能,因为在这之前,音频视频的播放只能依赖于 Flash。

一般而言,我们只需要建立如下 HTML 结构即可使用这项新技术:

<audio id="player" src="#"></audio>

播放之前让我们设置歌曲的地址,其中的 id 可以从网易云音乐网页版中的歌曲播放界面获取。

audio.src = `https://music.163.com/song/media/outer/url?id=${id}.mp3`

那么是如何通过 JavaScript 来控制它的播放、暂停等功能的呢,很简单:

let audio = document.querySelector('#player')
audio.play()
audio.pause()

播放器的控制器按钮的 HTML 结构如下

<div class="controller">
    <button class="icon icon-back"></button>
    <button class="icon icon-play paused"></button>
    <button class="icon icon-forward"></button>
</div>

接下来会涉及到逻辑控制部分,首先实例化一个播放器实例,Player类是我实现对 Audio 的包装类,其中的核心功能本质上是调用了 Audio API

var player = new Player()

接着音乐的播放、暂停、上一首和下一首都可以直接调用封装好的函数来执行。

player.play()
player.pause()
player.skipBack()
player.skipForward()

关于歌曲信息:

我首先调用后端代码批量生成指定ID的歌曲信息,并且提供JSON文件,而前端调用时只需读取JSON文件,接着实例化一个数组,用于存储所有的歌曲信息,当有需要的时候直接到数组中读取信息。数组中的每一条歌曲的数据结构如下:

{
    "id": 22,
    "url": "https://example.com/audio.mp3",
    "name": "Audio Name",
    "artist": "Audio Artist",
    "album": "Aduio Album",
    "duration": "05:55",
    "cover": "http://example.com/cover.jpg"
}

关于切换歌曲的上一首、下一首实现原理:

首先根据 index (歌曲在数组中的次序)获得歌曲信息(其中包括歌曲的mp3地址),然后JS调用如下代码即可完成歌曲的切换:

audio.src = `https://example.com/audio.mp3`
audio.play()

4)歌曲详情页的实现

关于唱片旋转功能的实现:

首先在css中定义动画关键帧

@keyframes rotate {
    from{-webkit-transform:rotate(0deg)}
    to{-webkit-transform:rotate(360deg)}
}

接着为唱片添加 css 属性,其中的20s代表唱片20秒旋转一圈,linear代表旋转速度为线性变化,infinite代表无限循环动画。

.cd-wrap {
    animation: 20s linear 0s normal none infinite rotate;
    animation-play-state: paused;
}

关于歌词的滚动实现:

首先从lrc文件中读入所有歌词,根据当前歌曲的播放进度来滚动到歌词的所在位置。

<div class="music-lrc">
    <li>歌词1</li>
    <li>歌词2</li>
    <li>歌词3</li>
</div>

关于歌曲进度条的实现:

歌曲进度条分为三条:缓冲条、播放条、总进度条。

这里实现了单击进度条进行进度跳转和拖拽进度条实现进度跳转,以下是核心代码:

initPlaybar () {
    const rect = this.template.progressBar.getBoundingClientRect()
    const thumbMove = (ev) => {
        let per = (ev.clientX - rect.left) / rect.width
        per = Math.max(per, 0)
        per = Math.min(per, 1)
        this.player.bar.set('played', per, 'width')
        this.player.template.ptime.innerText = utils.secondToTime(per * this.player.duration)
    }
    const thumbUp = (ev) => {
        document.removeEventListener('mouseup', thumbUp)
        document.removeEventListener('mousemove', thumbMove)
        let per = (ev.clientX - rect.left) / rect.width
        per = Math.max(per, 0)
        per = Math.min(per, 1)
        this.player.bar.set('played', per, 'width')
        this.player.seek(per * this.player.duration)
        this.player.disableTimeupdate = false
    }

    this.template.progressBar.addEventListener('mousedown', () => {
        this.player.disableTimeupdate = true
        document.addEventListener('mousemove', thumbMove)
        document.addEventListener('mouseup', thumbUp)
    })
}

5)歌曲搜索功能的实现

搜索功能无非是搜索性能上的优化,由于这里只测试了500多首歌曲,所以不考虑算法,直接调用JS代码对数组中的歌曲名称进行搜索,将搜索到的歌曲调用视图渲染直接显示出来。

let search = (keyword) => {
    const audios = this.audios.filter((item)=>{
        return (item.name.indexOf(keyword) != -1)
    })
    if (audios) {
        this.clear()
        this.add(audios)
    }
}

6)关于用到的技术

大概有webpack、scss、svg、iconfont、模块化开发、NodeJS等。

4、成果展示

1)首屏页面

首屏界面.png

2)歌曲详情界面

歌曲详情.png

当歌曲处于播放状态时,唱片旋臂自动旋下,唱片自动旋转,歌词自动切换。

5、心得体会及建议

在整体的开发过程中,我是一边学习一边进行开发的,也遇到了不少问题,但都被我一一解决。通过查阅MDN上的文档,可以比较全面地了解各项技术。项目是使用了模块化开发技术并使用Webpack对代码进行打包,这不但提高了项目的开发效率,并且提高了代码的复用性,使各个模块之间的条理更加清晰,能够较好地互相协同工作。而逻辑代码部分使用了ES6标准的JavaScript进行开发,这对于老旧的浏览器来说兼容性不太好,于是使用了Babel对代码进行转译,确保可以兼容比较旧的浏览器。关于歌曲信息数据的获取,后端使用NodeJS根据 Github 上开源的网易云音乐API获取了500多首歌曲的信息,便于前端调用。整个项目开发下来,收获良多,获益匪浅。