Java播放歌词同步源码,Android 实现歌词同步

歌词同步的原理其实很简单:

歌词显示是一个线程, 音乐播放时一个线程,通过播放时间将歌词显示进度与播放进度同步起来。

网络标准的歌词格式是LRC。 我们看下一个LRC文档,其格式就一目了然了。

[ti:爱]

[ar:小虎队]

[al:华纳国语情浓13首]

[by:爱上你了音乐网]

[02:08.00][00:38.00]把你的心、我的心串一串

[02:11.00][00:41.00]串一株幸运草、串一?同心圆

[02:16.00][00:46.00]让所有期待未?的呼唤

[02:19.00][00:49.00]趁青春做?伴

[03:16.00][02:24.00][00:53.00]?让年轻越长大越孤单

[03:19.00][02:27.00][00:56.00]把我的幸运草种在你的梦田

[03:23.00][02:31.00][01:01.00]让地球随我?的同心圆

LRC 格式为 [歌词显示起始时间][歌词显示结束时间]歌词内容。

了解歌词同步原理,我们可以想到要做如下工作:

1. LRC 解析

2. LRC 歌词显示

3. 歌词与播放音乐同步

4. 歌词的获取

一 LRC解析

这边我推荐YOYOPlayer 音乐播放开源项目。 源代码已经非常好的支持了LRC解析。 我拿过来就用了。

过程大概如此: 把LRC文件读到内存里面,用 sentence数据结构存放。 Sentence里面有 Fromtime, Totime, content三个成员变量。显示的时候需要这些数据。

二。 LRC歌词显示

歌词的绘制通过重写 OnDraw方法。

绘制的代码贴出来:

java代码:

01

long t = tempTime;

02

int index = getNowSentenceIndex(t);

03

if (index == -1) {

04

return;

05

}

06

Sentence now = list。get(index);

07

float f = (t - now。getFromTime()) *1.0f/ (now.getToTime() - now.getFromTime());

08

if (f >0.98f) {

09

f =0.98f;

10

}

11

Shader shader =new LinearGradient(0,0,now。getContentWidth(mTxtPaint),0,new int[] { Color.RED,Color.BLUE },new float[] { f, f +0.01f },TileMode.CLAMP);

12

mTxtPaint.setShader(shader);

13

canvas.drawText(now.getContent(),0,20, mTxtPaint);

上面的代码很简单,关键一个函数是getNowSentenceIndex(t). 通过播放时间来获得歌词的索引. 我们看下getNowSentenceIndex()如何实现.   java代码:

1

private int getNowSentenceIndex(long t) {

2

for (int i =0; i < list.size(); i++) {

3

if (list.get(i).isInTime(t)) {

4

return i;

5

}

6

}

7

// throw new RuntimeException("竟然出现了找不到的情况!");

8

return -1;

9

}

还有一个歌词渐变的效果,其关键代码在与对画笔的设置,如下.   java代码:

1

Shader shader =new LinearGradient(0,0,

2

now.getContentWidth(mTxtPaint),0,new int[] { Color.RED,Color.BLUE },new float[] { f, f +0.01f },TileMode.CLAMP);

3

mTxtPaint.setShader(shader);

三. 歌词与播放音乐同步   音乐播放的时候,同时启动歌词显示线程. 将音乐播放的时间设置到歌词View的成员变量中, 以达到同步的目的.   java代码:

1

private class MyHandlerextends Handler {

2

@Override

3

public void handleMessage(Message msg) {

4

// Log.v("#################hahah", "" + mp.getCurrentPosition());

5

// 重画

6

lrcView.mLyric.setTime(mp.getCurrentPosition());

7

lrcView.invalidate();

8

}

9

}

四. 歌词的获取   歌词的获取是通过百度搜索出来的. 具体代码如下,很好看懂,关键代码如下:   java代码:

1

GetMethod get =new GetMethod("http://www.baidu.com/s?wd=" + URLEncoder.encode("filetype:lrc " + key,"GBK"));

2

get.addRequestHeader("Host","www.baidu.com");

3

get.addRequestHeader("User-Agent","Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11");

4

get.addRequestHeader("Accept","text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");

5

get.addRequestHeader("Accept-Language","zh-cn,zh;q=0.5");

6

get.addRequestHeader("Keep-Alive","300");

7

get.addRequestHeader("Referer","http://www.baidu.com/");

8

get.addRequestHeader("Connection","keep-alive");

9

int i = http.executeMethod(get);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/346346.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

矩阵连乘 动态规划_Java动态规划

1. 介绍动态规划典型的被用于优化递归算法&#xff0c;因为它们倾向于以指数的方式进行扩展。动态规划主要思想是将复杂问题(带有许多递归调用)分解为更小的子问题&#xff0c;然后将它们保存到内存中&#xff0c;这样我们就不必在每次使用它们时重新计算它们。要理解动态规划的…

c php乱码,php分割GBK中文乱码的解决方法

类似如下的字符串(GBK), explode不能得到正确结果:$result explode("|", "滕华弢|海青");究其原因, 对于”弢”字(读tao,不认识没关系,我也不认识), 因为他的GBK编码值为: 8f7c, 不巧的是, “|”的ASCII值也是7c.还有一些类似的问题: 因为GBK编码的编码范…

分布式光伏补贴_光伏发电上网电价政策综述

原标题&#xff1a;光伏发电上网电价政策综述近些年&#xff0c;光伏发电上网电价相关政策不断推陈出新&#xff0c;在推进平价上网的同时&#xff0c;也积极对接了电力市场建设需要。本文梳理了光伏发电上网电价及补贴标准有关政策&#xff0c;供参考使用&#xff1a;1.普通光…

怎么简单的锁定文件夹_简单性与鲁棒性–在锁定文件处理中展示

怎么简单的锁定文件夹今天&#xff0c;我们将讨论使事情保持简单&#xff0c;愚蠢&#xff08;KISS&#xff09;和鲁棒性的设计价值之间&#xff0c;设计不足和过度设计之间的冲突。 我们正在编写一个批处理Java应用程序&#xff0c;需要确保在服务器上一次最多运行一个实例。…

php strlen 线程安全,浅析PHP中strlen和mb_strlen的区别

在PHP中&#xff0c;strlen与mb_strlen是求字符串长度的函数&#xff0c;但是对于一些初学者来说&#xff0c;如果不看手册&#xff0c;也许不太清楚其中的区别。下面通过例子&#xff0c;讲解这两者之间的区别。先看例子&#xff1a;//测试时文件的编码方式要是UTF8$str中文a字…

单片机float数发给上位机_上位机倒计时器

1. 设置窗口在VS2019新建一个Windows窗体应用(.NET Framework)项目&#xff0c;新建之后出现一个可视化页面(From1.cs[设计])设置窗口。在左侧的工具箱里面拉拽控件到操作面板上&#xff0c;按照自己的喜好摆放位置和调大小。这里要注意的是用到的分别是什么控件&#xff1a;文…

JDK语言功能预览:切换表达式

JEP 12 [“预览语言和VM功能”]在其主页上描述如下&#xff1a; 预览语言或VM功能是Java SE平台的一项新功能&#xff0c;该功能已完全指定&#xff0c;完全实现但不是永久性的。 JDK功能发布中提供了该功能&#xff0c;以根据实际使用情况激发开发人员反馈。 这可能会导致它在…

python快速示例_Python编程入门-基本示例,快速,上,手,基础

环境配置安装Python&#xff0c;目前最新的是3.9(不支持Windows7)&#xff0c;我装的3.7https://www.python.org/downloads/安装向导里勾选自动添加路径&#xff0c;装完就可以用&#xff0c;Windows10/7搜索框输入IDLE&#xff0c;进入交互式环境窗口&#xff0c;输入语句后&a…

php 距离排序,php 附近由近到远排序查询

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼//获取经纬度 默认值为0.5千米function returnSquarePoint($lng, $lat, $distance 0.5){define(EARTH_RADIUS, 6371); //地球半径&#xff0c;平均半径为6371km$dlng 2 * asin(sin($distance / (2 * EARTH_RADIUS)) / cos(deg2ra…

土地利用覆被变化的概念_欠压实概念极其荒谬

●李传亮地表疏松的沉积物&#xff0c;孔隙度极高&#xff0c;有时可高达80%以上&#xff0c;但随着埋藏深度的加大&#xff0c;在上覆压力的作用下&#xff0c;其排列方式不断由松散排列趋于致密排列&#xff0c;同时伴随有孔隙度的大幅度减小&#xff0c;此即岩石的压实阶段&…

java方法带参数返回值_Java方法中的参数太多,第6部分:方法返回

java方法带参数返回值在当前的系列文章中&#xff0c;我正在致力于减少调用Java方法和构造函数所需的参数数量&#xff0c;到目前为止&#xff0c;我一直专注于直接影响参数本身的方法&#xff08; 自定义类型 &#xff0c; 参数对象 &#xff0c; 构建器模式 &#xff0c; 方法…

java足球游戏毕业设计,java毕业设计_springboot框架的校园足球管理平台

今天介绍一个java毕设题目, 题目内容为springboot框架的校园足球管理平台, 是一个采用b/s结构的javaweb项目, 采用java语言编写开发工具eclipse, 项目框架jspspringbootmybatis, 校园足球管理平台的信息存储于mysql中, 并基于mybatis进行了orm封装, 该校园足球管理平台系统通过…

python 爬取贝壳网小区名称_用Python爬取贝壳网新房和二手房数据

[Python] 纯文本查看 复制代码import randomimport requestsfrom bs4 import BeautifulSoupimport reimport mathfrom lxml import etreeUSER_AGENTS ["Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)&q…

Java 11功能– Java飞行记录器

在本文中&#xff0c;我们将看到如何利用Java Flight Recorder功能作为Java 11的一部分。之前&#xff0c;它是商业功能之一。 但是&#xff0c;对于带有JEP 328的 Java 11&#xff0c;它是开源的。 Java Flight Recorder将OS和JVM事件记录到一个文件中&#xff0c;可以使用Jav…

MATLAB slider中的数值,在微信小程序中如何使用slider设置数据值

这篇文章主要介绍了微信小程序使用slider设置数据值及switch开关组件功能,结合实例形式分析了slider组件及switch组件的功能与使用方法,并附带源码供读者下载参考,需要的朋友可以参考下本文实例讲述了微信小程序使用slider设置数据值及switch开关组件功能。分享给大家供大家参考…

qstandarditemmodel 重写data函数后无法实现拖拽_实现类似百度网盘上传的功能

今天写到了上传文件部分&#xff0c;记录一下。前端使用了dropzone.js(用于实现文件上传的JS库)&#xff0c;并对此文件进行了细微修改。说一下思路吧&#xff1a;首先界面长这样&#xff1a;点击上传文件&#xff0c;需要弹出一个对话框&#xff0c;对话框中有支持拖拽文件的文…

逻辑斯蒂回归_逻辑斯蒂回归详细解析 | 统计学习方法学习笔记 | 数据分析 | 机器学习...

本文包括&#xff1a;重要概念逻辑斯蒂回归和线性回归二项逻辑斯谛回归模型逻辑斯蒂回顾与几率模型参数估计多项逻辑斯谛回归其它有关数据分析&#xff0c;机器学习的文章及社群1.重要概念&#xff1a;在正式介绍逻辑斯蒂回归模型之前&#xff0c;需要先对一些基本概念有所了解…

mysql 数据传输 定时,MySQL数据库定时备份的实现方法

1. 创建shell脚本2. 给shell脚本添加执行权限3. 给脚本添加定时任务crontab文件的说明&#xff1a;用户创建的crontab文件中&#xff0c;每一行都代表一项定时任务&#xff0c;每行的每个字段代表一项设置&#xff0c;它的格式每行共分为六个字段&#xff0c;前五段是时间设定字…

python 生意_本周互联网关注(2015515):劳动人民的生意经、python好还是go好

我很喜欢写这种类型的文章&#xff0c;写的也轻松&#xff0c;大家看的也多。性价比高。那么现在继续。一、所谓光辉岁月&#xff0c;不是波澜壮阔的时候&#xff0c;而是无人问津时&#xff0c;你对梦想的坚持。| 陈欧很多人刚开始创业时激情无比高涨&#xff0c;干着干着开始…

mysql空洞数据,Mysql 表空间和 数据页空洞

一、表空间1、表空间&#xff1a; innodb 引擎存储的最高层&#xff1b; 存放所有的数据2、独立表空间&#xff1a;Mysql 版本5.6 后默认开启的单表单空间(1)Innodb 默认存储引擎页的大小为 16K &#xff1b;默认表空间 大小为96k(2)独立表空间 开启方式 innodb_file_per_table…