`
wuchengyi2015106
  • 浏览: 25022 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

实现歌词同步源码

阅读更多

实现歌词同步

介绍:

利用TextView实现歌词同步显示,这是一个简单的利用TextView实现滚动实时显示歌词的。
里面的内容都已经写上了详细的注释。里面播放音乐的时候歌词同步展示。
做媒体这块的朋友可以学习一下,练练歌词同步实现方法。
歌词实现展示类TextShow,

项目源码来源:http://www.itlanbao.com/code/20151214/10000/100695.html

效果截图:

 

主要代码如下:

package com.example.textviewchange;

import java.io.BufferedReader;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.widget.TextView;

public class MainActivity extends Activity {
	private MediaPlayer player;
	private TextView tv;
	private boolean flag=false;//用来停止和判断线程
	private int i;
	private TextShow ts;
	private Map<String,String> map,map1;
	private int count=5;
	private List<String> list;
	private String s="";
	private boolean change=false;
	Looper looper=Looper.getMainLooper();
	Handler handler=new Handler(looper){
		public void handleMessage(android.os.Message msg) {
			if(msg.what==10&&flag==false){
				
				if(i==map1.size()){//判断歌词是不是已经全部显示
					flag=true;
			//如果销毁了activity则,不执行下面的方法
					return;
				}
				Changetext();
			}
		};
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		tv=(TextView)findViewById(R.id.tv);
		//获取assert中的歌曲文件以及歌词文件
		AssetManager am=getAssets();
		AssetFileDescriptor afd;
		//使用媒体播放器
		player=new MediaPlayer();
		//设置播放的音频类型
		player.setAudioStreamType(AudioManager.STREAM_MUSIC);
		try {
			afd = am.openFd("apple.mp3");
			FileDescriptor fd=afd.getFileDescriptor();
			player.setDataSource(fd);
			//获取sd卡中的歌曲文件
			//player.setDataSource("/sdcard/Music/apple.mp3");
			player.prepare();
			
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		//开始播放
		player.start();
		//测试,这里应该用输入输出流读取文件
		map1=new HashMap<>();
		list=new  ArrayList<>();
		//加载歌词文件
		read();
		
		//保留插入顺序
		//设置给显示界面刚开始显示5行
				map=new LinkedHashMap<String,String>();
				for(int i=0;i<5;i++){
					map.put(list.get(i), map1.get(list.get(i)));
				}
				ts=new TextShow(map);
		
		new Thread(){
			public void run() {
				while(!flag){
					
					try {
						sleep(500);
						Message mes=new Message();
						mes.what=10;
						handler.sendMessage(mes);
						
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
				
			};
		}.start();
	}
	public void Changetext(){
		//给正在播放的歌词添加样式
		if(map!=null&&map.get(conTime(player.getCurrentPosition()))!=null){
			String s1="";
			tv.setText(ts.Add(conTime(player.getCurrentPosition()).toString()));
			s1=conTime(player.getCurrentPosition()).toString();
			//判断在相同的时间段内,Changetext方法是不是执行了两次
			if(!s.equals(s1)){
				change=true;
				s=s1;
			}else{
				change=false;
			}
			if(change){
			//设置正在播放的歌词的上方的行数
			if(i>5){
				//移除最顶部的一行
				map.remove(list.get(i-6));
			}
				//增加一行在最底部
			if(count<map1.size()){
			map.put(list.get(count), map1.get(list.get(count)));
			}
			i++;
			count++;
			}
		}
		
		
	}
	//读取LRC的歌词文件
	public void read(){
		try {
			InputStream in=getAssets().open("c.lrc");
			BufferedReader bf=new BufferedReader(new InputStreamReader(in));
			String msg="";
			while((msg=bf.readLine())!=null){
				if(msg.length()!=0){
					//保存歌词的时间以及歌词内容
					map1.put(msg.substring(1,6), msg.substring(msg.lastIndexOf("]")+1)+"\n");
					//保存每一行歌词的时间
					list.add(msg.substring(1,6));
				}
			}
			bf.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	@Override
	protected void onDestroy() {
		super.onDestroy();
		if(player!=null){
			player.stop();
			player.release();
			player=null;
		}
		flag=true;
	}
	//将音频的播放时间转换成00:00的格式
	public CharSequence conTime(int duration) {
		
		int second=duration/1000;
		int miunte=second/60;
		second=second%60;
		String miunte1 = String.valueOf(miunte);
		String second1 = String.valueOf(second);
		if(miunte<10){
			miunte1="0"+miunte;
		}if(second<10){
			second1="0"+second;
		}
		
		return miunte1+":"+second1;
	}
}

 

 特殊文字显示 (歌词同步显示)

package com.example.textviewchange;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import android.graphics.Color;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.style.AbsoluteSizeSpan;
import android.text.style.ForegroundColorSpan;
/*
 *	特殊文字显示 (歌词同步显示)
 * */
public class TextShow {
	private SpannableStringBuilder ssb;
	private SpannableString ss;
	//private String str;
	private Map<String,String> map;
	//传入的map必须为LinkedHashMap
	public TextShow(Map<String,String> map) {
		this.map=map;
		ssb=new SpannableStringBuilder();
	}
	//设置字符串的样式(如果要分行显示,在传入的字符串中添加"\n")
	//根据字符串从map中取值
	public SpannableString changeText(String str){
		ss=new SpannableString(str);
		//设置字符串的大小
		ss.setSpan(new AbsoluteSizeSpan(50),0,ss.length(),Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		//设置字符串的颜色
		ss.setSpan(new ForegroundColorSpan(Color.MAGENTA), 0, ss.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		return ss;
	}
	//追加到SpannableStringBuilder中某一行
	
	//ss 需要追加的有样式的字符串
	public SpannableStringBuilder Add(String str){
		//清除上一次的数据
		ssb.clear();
		//遍历map
		Iterator<Entry<String, String>> iter = map.entrySet().iterator();
		while (iter.hasNext()) {
			Map.Entry<String,String> entry = (Map.Entry<String,String>) iter.next();
				String key = entry.getKey();
				String val = entry.getValue();
		if(key.equals(str)){
			
			ssb.append(changeText(val));
			}
		else{
			SpannableString ss1=new SpannableString(val);
			ssb.append(ss1);
		}
		
		}
		/* 也可以用下面的方法
		 * for(String string:map.values()){
			if(string.equals(map.get(str))){
				ssb.append(changeText(str));
			}else{
			SpannableString ss1=new SpannableString(string);
			ssb.append(ss1);
			
			}
			
		}*/
		return ssb;
	}
}

 

0
0
分享到:
评论

相关推荐

    网页歌词同步播放器源码

    网页歌词同步播放器是一种在网页上实现音乐播放并同时展示逐字逐句歌词的应用,它让用户在...对于经验丰富的开发者,这个源码可能提供了一个快速实现歌词同步播放功能的基础,通过调整和优化,可以适应更复杂的需求。

    易语言源码歌词同步源码.rar

    标题提到的"易语言源码歌词同步源码.rar"是一个压缩包文件,其中包含了使用易语言编写的歌词同步功能的源代码。这种源码可能用于开发音乐播放软件,实现歌词与音乐的精准匹配,为用户提供更好的听歌体验。 在易语言...

    安卓textView相关-TextView实现歌词同步.rar

    在本次分享的“安卓textView相关-TextView实现歌词同步.rar”压缩包中,主要探讨了如何利用TextView来实现实时的歌词同步功能。这个功能在音乐播放应用中很常见,能够给用户带来更好的视听体验。下面我们将详细解析...

    歌词同步播放器源码

    歌词同步播放器是一款基于Android平台的应用...通过分析和研究这个歌词同步播放器的源码,开发者可以深入了解Android多媒体处理、UI设计、数据存储以及多线程编程等多个方面,为今后的Android应用开发积累宝贵经验。

    安卓Android源码——卡拉OK,歌词同步程序.zip

    这个“安卓Android源码——卡拉OK,歌词同步程序”压缩包包含了一个实现歌词显示与音乐播放同步的示例项目,这对于想要在音乐应用中集成这一功能的开发者具有很高的学习价值。 首先,我们要理解歌词同步的基本原理...

    JS 网页播放器实现歌词同步

    在网页开发中,实现歌词同步是一项常见的需求,特别是在音乐播放应用或者个人网页中播放音乐时。这个主题“JS 网页播放器实现歌词同步”主要涵盖了JavaScript编程、HTML页面结构以及XML数据处理等关键知识点。下面将...

    易语言歌词同步DOS版

    在DOS环境下实现歌词同步,需要处理好时间控制和文本显示,这通常涉及定时器和事件驱动的编程技术。 3. **DOS版**:DOS(Disk Operating System)是早期个人计算机上广泛使用的操作系统,它是一个命令行界面,没有...

    酷狗歌词效果源码

    综上所述,"酷狗歌词效果源码"是一个涵盖了歌词解析、时间同步、动画效果实现、用户界面设计等多个方面的项目。开发者可以通过研究这个源码,学习如何创建类似的桌面歌词效果,提升音乐播放软件的用户体验。在Test5...

    jQuery实现的jplayer歌词同步音乐播放器特效源码.zip

    在实现歌词同步时,关键在于获取歌词文件(通常是.lrc格式)并解析其中的时间戳。lrc文件由一系列的时间标签和对应歌词组成,例如: ``` [00:00.00] 我是第一句歌词 [00:15.00] 这是第二句歌词 ``` 代码需要遍历...

    lrcDemo歌词同步滚动显示

    本篇将深入探讨“lrcDemo”这个项目,它是一个实现歌词同步滚动显示的源码示例,对于开发者来说具有很高的学习价值。 首先,我们要了解什么是LRC格式。LRC是Lyric(歌词)的缩写,是一种专门用于存储歌词的文本文件...

    易语言歌词同步DOS版源码

    4. **时间同步技术**:实现歌词同步的关键在于正确地将歌词与音频播放进度关联起来。这可能涉及到计时器中断、音乐播放器API的调用,以及对音频播放速率的处理。 5. **文本输出**:在DOS环境下,没有图形用户界面,...

    网页模板——jQuery实现的jplayer歌词同步音乐播放器特效源码.zip

    接下来,我们关注的重点是如何实现歌词同步。这通常涉及到LRC文件格式,这是一种用于存储歌词的时间轴信息的文本文件格式。每行歌词后面会跟一个时间戳,表示该歌词何时应该显示。在播放音乐时,程序需要实时解析LRC...

    HTML网页歌曲播放器 歌词同步

    - 实现歌词同步显示的核心在于根据音频播放进度动态更新歌词显示内容。 - 通常会利用JavaScript监听音频播放事件(如`timeupdate`),并根据当前播放时间与歌词数据中的时间戳匹配来实现歌词的自动滚动。 3. **跨...

    天天动听悬浮歌词源码

    通过分析和理解这个文件,我们可以学习如何创建浮动窗口,加载和解析LRC文件,实现歌词同步,以及处理与播放器的交互。这对于想要开发类似功能或者深入理解Android系统级别的应用开发的开发者来说,是一份宝贵的参考...

    Android 音乐播放器歌词列表式同步显示功能源码.zip

    总的来说,这份Android音乐播放器歌词同步显示的源码涵盖了文件解析、时间同步、界面设计等多个方面,对于想要深入Android音频应用开发的开发者来说,是一份宝贵的学习资料。通过学习和实践,不仅可以提升编程技能,...

    Android源码——卡拉OK,歌词同步程序.zip

    为了实现歌词同步显示,开发者通常会创建一个LyricView或类似视图,用于显示滚动的歌词。当音频播放到某一时间点时,LyricView会高亮对应的歌词行。这可能涉及到对时间戳的比较和动画效果的处理,例如使用Handler或...

    易语言源码易语言歌词显示源码.rar

    2. 时间同步:为了实现歌词与音乐的同步显示,源码需要能够读取音频文件的信息,获取当前播放时间,并根据时间戳更新歌词。 3. 用户界面设计:为了让用户能够清晰地看到歌词,源码还需要创建一个用户界面,可能包括...

    易语言源码易语言lrc歌词播放源码.rar

    这可能通过注册播放器事件或定时器来实现,确保歌词的更新与音乐播放同步。 3. **用户界面**:为了展示歌词,程序需要一个用户界面,通常包括歌词显示区域和控制按钮(如播放、暂停、前进、后退等)。易语言提供了...

Global site tag (gtag.js) - Google Analytics