GVKun编程网logo

JS实现网页手机音乐播放器歌词同步播放功能代码(js音乐播放器显示歌词)

16

在本文中,您将会了解到关于JS实现网页手机音乐播放器歌词同步播放功能代码的新资讯,同时我们还将为您解释js音乐播放器显示歌词的相关在本文中,我们将带你探索JS实现网页手机音乐播放器歌词同步播放功能代码

在本文中,您将会了解到关于JS实现网页手机音乐播放器歌词同步播放功能代码的新资讯,同时我们还将为您解释js音乐播放器显示歌词的相关在本文中,我们将带你探索JS实现网页手机音乐播放器歌词同步播放功能代码的奥秘,分析js音乐播放器显示歌词的特点,并给出一些关于Android实现音乐播放器歌词显示效果、android暂停或停止其他音乐播放器的播放实现代码、Android音乐播放器实践 -- Hide音乐播放器1.0版、Delphi 音乐播放器系列[频谱、歌词、打开文件、播放进度]的实用技巧。

本文目录一览:

JS实现网页手机音乐播放器歌词同步播放功能代码(js音乐播放器显示歌词)

JS实现网页手机音乐播放器歌词同步播放功能代码(js音乐播放器显示歌词)

本文主要为大家分享一篇原生JS实现网页手机音乐播放器 歌词同步播放的示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧,希望能帮助到大家。


//获取歌词文本 
var txt = document.getElementById(lrc); 
var lrc = txt.value;//获取文本域里的值 
/*console.log(lrc);*/ 
var lrcArr = lrc.split([);//去除[ 
/*console.log(lrcArr);*/ 
var html = ;//定义一个空变量保存文本 
for(var i=0 ; i<lrcArr.length ; i++) 
{ 
  var arr = lrcArr[i].split(]); 
  /*console.log(arr[1]);*/ 
  var allTime = arr[0].split(.); 
  var time = allTime[0].split(:); 
  //获取分钟 秒钟 把时间换算成秒钟 
  var timer = time[0]*60 + time[1]*1; 
  var text = arr[1]; 
  if(text) 
  { 
    html += <p id=+timer+>+text+</p> 
  } 
  con.innerHTML = html     <pre class=html name=code>}</pre> 
<pre></pre> 
<p></p> 
<p>实现歌词同步首先要获取到文本框 再配合H5中新增的属性如图 其实很简单啦!</p> 
<p></p> 
<p><pre class=html name=code>    //监听音乐播发进度实现歌词同步 
myMusic.addEventListener(timeupdate,function(){ 
  //获取当前播放时间 
  var curTime = parseInt(this.currentTime); 
  if(document.getElementById(curTime)) 
  { 
    for(var i=0 ; i<oP.length ; i++) 
    { 
oP[i].style.csstext = color:#ccc;font-size:12px;; 
    } 
    document.getElementById(curTime).style.csstext=color:rgb(242,110,111);font-size:18px;; 
    if (oP[num+7].id == curTime)//判断成功一次num++ 
    { 
con.style.top = -20*num +px; 
num++; 
    } 
  } 
});</pre></p> 
<pre></pre>

相关推荐:

如何用html5 写出网页音乐播放器

html网页音乐播放器自带播放列表_PHP教程

html网页音乐播放器自带播放列表

Android实现音乐播放器歌词显示效果

Android实现音乐播放器歌词显示效果

这两天有个任务,说是要写一个QQ音乐播放器歌词的那种效果,毕竟刚学自定义View,没有什么思路,然后就Google.写了一个歌词效果,效果图在后面,下面是我整理的代码。

首先实现这种效果有两种方式:

1.自定义View里重载onDraw方法,自己绘制歌词

2.用ScrollView实现

第一种方式比较精确,但要支持滑动之后跳转播放的话难度很大,所以我选择第二种,自定义ScrollView。

我也不多说,直接上代码,代码中有注释。

一.自定义LycicView extends ScrollView

里面包括一个空白布局,高度是LycicView的一半,再是一个布局存放歌词的,最后是一个空白布局高度是LycicView的一半。

这里动态的向第二个布局里面添加了显示歌词的TextView,并利用ViewTreeObserver得到每个textview的高度,方便知道每个textview歌词所要滑动到的高度。

public class LycicView extends ScrollView {
 LinearLayout rootView;//父布局
 LinearLayout lycicList;//垂直布局
 ArrayList<TextView> lyricItems = new ArrayList<TextView>();//每项的歌词集合
 
 ArrayList<String> lyricTextList = new ArrayList<String>();//每行歌词文本集合,建议先去看看手机音乐里的歌词格式和内容
 ArrayList<Long> lyricTimeList = new ArrayList<Long>();//每行歌词所对应的时间集合
 ArrayList<Integer> lyricItemHeights;//每行歌词TextView所要显示的高度
 
 int height;//控件高度
 int width;//控件宽度
 int prevSelected = 0;//前一个选择的歌词所在的item
 
 
 public LycicView(Context context) {
 super(context);
 init();
 }
 
 public LycicView(Context context, AttributeSet attrs) {
 super(context, attrs);
 init();
 }
 
 public LycicView(Context context, AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);
 init();
 }
 private void init(){
 rootView = new LinearLayout(getContext());
 rootView.setOrientation(LinearLayout.VERTICAL);
 //创建视图树,会在onLayout执行后立即得到正确的高度等参数
 ViewTreeObserver vto = rootView.getViewTreeObserver();
 vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
 @Override
 public void onGlobalLayout() {
 height = LycicView.this.getHeight();
 width = LycicView.this.getWidth();
 
 refreshRootView();
 
 }
 });
 addView(rootView);//把布局加进去
 }
 
 /**
 *
 */
 void refreshRootView(){
 rootView.removeAllViews();//刷新,先把之前包含的所有的view清除
 //创建两个空白view
 LinearLayout blank1 = new LinearLayout(getContext());
 LinearLayout blank2 = new LinearLayout(getContext());
 //高度平分
 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(width,height/2);
 rootView.addView(blank1,params);
 if(lycicList !=null){
 rootView.addView(lycicList);//加入一个歌词显示布局
 rootView.addView(blank2,params);
 }
 
 }
 
 /**
 *设置歌词,
 */
 void refreshLyicList(){
 if(lycicList == null){
 lycicList = new LinearLayout(getContext());
 lycicList.setOrientation(LinearLayout.VERTICAL);
 //刷新,重新添加
 lycicList.removeAllViews();
 lyricItems.clear();
 lyricItemHeights = new ArrayList<Integer>();
 prevSelected = 0;
 //为每行歌词创建一个TextView
 for(int i = 0;i<lyricTextList.size();i++){
 final TextView textView = new TextView(getContext());
 
 textView.setText(lyricTextList.get(i));
 //居中显示
 LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
 params.gravity = Gravity.CENTER_HORIZONTAL;
 textView.setLayoutParams(params);
 //对高度进行测量
 ViewTreeObserver vto = textView.getViewTreeObserver();
 final int index = i;
 vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
 @Override
 public void onGlobalLayout() {
 textView.getViewTreeObserver().removeOnGlobalLayoutListener(this);//api 要在16以上 >=16
 lyricItemHeights.add(index,textView.getHeight());//将高度添加到对应的item位置
 }
 });
 lycicList.addView(textView);
 lyricItems.add(index,textView);
 }
 }
 }
 /**
 * 滚动到index位置
 */
 public void scrollToIndex(int index){
 if(index < 0){
 scrollTo(0,0);
 }
 //计算index对应的textview的高度
 if(index < lyricTextList.size()){
 int sum = 0;
 for(int i = 0;i<=index-1;i++){
 sum+=lyricItemHeights.get(i);
 }
 //加上index这行高度的一半
 sum+=lyricItemHeights.get(index)/2;
 scrollTo(0,sum);
 }
 }
 
 /**
 * 歌词一直滑动,小于歌词总长度
 * @param length
 * @return
 */
 
 int getIndex(int length){
 int index = 0;
 int sum = 0;
 while(sum <= length){
 sum+=lyricItemHeights.get(index);
 index++;
 }
 //从1开始,所以得到的是总item,脚标就得减一
 return index - 1;
 }
 
 /**
 * 设置选择的index,选中的颜色
 * @param index
 */
 void setSelected(int index){
 //如果和之前选的一样就不变
 if(index == prevSelected){
 return;
 }
 for(int i = 0;i<lyricItems.size();i++){
 //设置选中和没选中的的颜色
 if(i == index){
 lyricItems.get(i).setTextColor(Color.BLUE);
 }else{
 lyricItems.get(i).setTextColor(Color.WHITE);
 }
 prevSelected = index;
 }
 }
 
 /**
 * 设置歌词,并调用之前写的refreshLyicList()方法设置view
 * @param textList
 * @param timeList
 */
 public void setLyricText(ArrayList<String> textList,ArrayList<Long> timeList){
 //因为你从歌词lrc里面可以看出,每行歌词前面都对应有时间,所以两者必须相等
 if(textList.size() != timeList.size()){
 throw new IllegalArgumentException();
 }
 this.lyricTextList = textList;
 this.lyricTimeList = timeList;
 
 refreshLyicList();
 }
 
 @Override
 protected void onScrollChanged(int l, int t, int oldl, int oldt) {
 super.onScrollChanged(l, t, oldl, oldt);
 //滑动时,不往回弹,滑到哪就定位到哪
 setSelected(getIndex(t));
 if(listener != null){
 listener.onLyricScrollChange(getIndex(t),getIndex(oldt));
 }
 }
 OnLyricScrollChangeListener listener;
 public void setOnLyricScrollChangeListener(OnLyricScrollChangeListener l){
 this.listener = l;
 }
 
 /**
 * 向外部提供接口
 */
 public interface OnLyricScrollChangeListener{
 void onLyricScrollChange(int index,int oldindex);
 }
}

二..MainActivity中的布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:background="@mipmap/img01"
 tools:context=".MainActivity">
 
 <EditText
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:inputType="number"
 android:ems="10"
 android:id="@+id/editText"
 android:layout_alignParentBottom="true"
 android:layout_alignParentLeft="true"
 android:layout_alignParentStart="true" />
 
 <Button
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:text="scroll to"
 android:id="@+id/button"
 android:layout_alignTop="@+id/editText"
 android:layout_alignParentRight="true"
 android:layout_alignParentEnd="true" />
 
 <RelativeLayout
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:layout_alignParentTop="true"
 android:layout_centerHorizontal="true"
 android:layout_above="@+id/editText">
 
 <custom.LycicView
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:id="@+id/view"
 android:layout_centerVertical="true"
 android:layout_centerHorizontal="true" />
 
 <View
 android:layout_width="match_parent"
 android:layout_height="2dp"
 android:background="@null"
 android:id="@+id/imageView"
 android:layout_centerVertical="true"
 android:layout_centerHorizontal="true" />
 <View
 android:layout_below="@id/imageView"
 android:layout_width="match_parent"
 android:layout_height="1dp"
 android:layout_marginTop="6dp"
 android:background="#999999"
 android:id="@+id/imageView2"
 android:layout_centerVertical="true"
 android:layout_centerHorizontal="true" />
 </RelativeLayout>
</RelativeLayout>

具体实现代码如下:

public class MainActivity extends AppCompatActivity {
 
 LycicView view;
 EditText editText;
 Button btn;
 Handler handler = new Handler(new Handler.Callback() {
 @Override
 public boolean handleMessage(Message msg) {
 if(msg.what == 1){
 
 if(lrc_index == list.size()){
 handler.removeMessages(1);
 }
 lrc_index++;
 
 System.out.println("******"+lrc_index+"*******");
 view.scrollToIndex(lrc_index);
 handler.sendEmptyMessageDelayed(1,4000);
 }
 return false;
 }
 });
 private ArrayList<LrcMusic> lrcs;
 private ArrayList<String> list;
 private ArrayList<Long> list1;
 private int lrc_index;
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 
 initViews();
 
 initEvents();
 }
 private void initViews(){
 view = (LycicView) findViewById(R.id.view);
 editText = (EditText) findViewById(R.id.editText);
 btn = (Button) findViewById(R.id.button);
 }
 private void initEvents(){
 InputStream is = getResources().openRawResource(R.raw.eason_tenyears);
 
 // BufferedReader br = new BufferedReader(new InputStreamReader(is));
 list = new ArrayList<String>();
 list1 = new ArrayList<>();
 lrcs = Utils.redLrc(is);
 for(int i = 0; i< lrcs.size(); i++){
 list.add(lrcs.get(i).getLrc());
 System.out.println(lrcs.get(i).getLrc()+"=====");
 list1.add(0l);//lrcs.get(i).getTime()
 }
 view.setLyricText(list, list1);
 view.postDelayed(new Runnable() {
 @Override
 public void run() {
 view.scrollToIndex(0);
 }
 },1000);
 
 btn.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 String text = editText.getText().toString();
 int index = 0;
 index = Integer.parseInt(text);
 view.scrollToIndex(index);
 }
 });
 view.setOnLyricScrollChangeListener(new LycicView.OnLyricScrollChangeListener() {
 @Override
 public void onLyricScrollChange(final int index, int oldindex) {
 editText.setText(""+index);
 lrc_index = index;
 System.out.println("===="+index+"======");
 //滚动handle不能放在这,因为,这是滚动监听事件,滚动到下一次,handle又会发送一次消息,出现意想不到的效果
 }
 });
 handler.sendEmptyMessageDelayed(1,4000);
 view.setOnTouchListener(new View.OnTouchListener() {
 @Override
 public boolean onTouch(View v, MotionEvent event) {
 switch (event.getAction()){
 case MotionEvent.ACTION_DOWN:
 handler.removeCallbacksAndMessages(null);
 
 System.out.println("取消了");
 break;
 case MotionEvent.ACTION_UP:
 System.out.println("开始了");
 handler.sendEmptyMessageDelayed(1,2000);
 break;
 case MotionEvent.ACTION_CANCEL://时间别消耗了
 break;
 }
 return false;
 }
 });
 
 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE|WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
 }
 
}

其中utils类和LycicMusic是一个工具类和存放Music信息实体类

Utils类

public class Utils {
 public static ArrayList<LrcMusic> redLrc(InputStream in) {
 ArrayList<LrcMusic> alist = new ArrayList<LrcMusic>();
 //File f = new File(path.replace(".mp3", ".lrc"));
 try {
 //FileInputStream fs = new FileInputStream(f);
 InputStreamReader input = new InputStreamReader(in, "utf-8");
 BufferedReader br = new BufferedReader(input);
 String s = "";
 
 while ((s = br.readLine()) != null) {
 if (!TextUtils.isEmpty(s)) {
 String lyLrc = s.replace("[", "");
 String[] data_ly = lyLrc.split("]");
 if (data_ly.length > 1) {
 String time = data_ly[0];
 String lrc = data_ly[1];
 LrcMusic lrcMusic = new LrcMusic(lrcData(time), lrc);
 alist.add(lrcMusic);
 }
 }
 }
 } catch (FileNotFoundException e) {
 e.printStackTrace();
 } catch (Exception e) {
 e.printStackTrace();
 }
 return alist;
 }
 public static int lrcData(String time) {
 time = time.replace(":", "#");
 time = time.replace(".", "#");
 
 String[] mTime = time.split("#");
 
 //[03:31.42]
 int mtime = Integer.parseInt(mTime[0]);
 int stime = Integer.parseInt(mTime[1]);
 int mitime = Integer.parseInt(mTime[2]);
 
 int ctime = (mtime*60+stime)*1000+mitime*10;
 
 return ctime;
 }
}

LrcMusic实体类  

public class LrcMusic {
 private int time;
 private String lrc;
 
 public LrcMusic() {
 }
 
 public LrcMusic(int time, String lrc) {
 this.time = time;
 this.lrc = lrc;
 }
 
 public int getTime() {
 return time;
 }
 
 public void setTime(int time) {
 this.time = time;
 }
 
 public String getLrc() {
 return lrc;
 }
 
 public void setLrc(String lrc) {
 this.lrc = lrc;
 }
}

效果图:

大体就这样,如有无情纠正,附上源码地址:点击打开链接

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

您可能感兴趣的文章:
  • android播放器实现歌词显示功能

android暂停或停止其他音乐播放器的播放实现代码

android暂停或停止其他音乐播放器的播放实现代码

代码如下:

复制代码 代码如下:

     public static final String PLAYSTATE_CHANGED = "com.android.music.playstatechanged";
    public static final String Meta_CHANGED = "com.android.music.Metachanged";
    public static final String QUEUE_CHANGED = "com.android.music.queuechanged";
    public static final String PLAYBACK_COMPLETE = "com.android.music.playbackcomplete";
    public static final String ASYNC_OPEN_COMPLETE = "com.android.music.asyncopencomplete";
    public static final String SERVICECMD = "com.android.music.musicservicecommand";
    public static final String CMDNAME = "command";
    public static final String CMDTOGGLEPAUSE = "togglepause";
    public static final String CmdsTOP = "stop";
    public static final String CMDPAUSE = "pause";
    public static final String CMDPREVIoUS = "prevIoUs";
    public static final String CMDNEXT = "next";


   private broadcastReceiver mIntentReceiver = new broadcastReceiver() {
        @Override
        public void onReceive(Context context,Intent intent) {
            String action = intent.getAction();
            String cmd = intent.getStringExtra("command");
            if (CMDNEXT.equals(cmd) || NEXT_ACTION.equals(action)) {
                next(true);
            } else if (CMDPREVIoUS.equals(cmd) || PREVIoUS_ACTION.equals(action)) {
                prev();
            } else if (CMDTOGGLEPAUSE.equals(cmd) || TOGGLEPAUSE_ACTION.equals(action)) {
                if (isPlaying()) {
                    pause();
                } else {
                    play();
                }
            } else if (CMDPAUSE.equals(cmd) || PAUSE_ACTION.equals(action)) {
                pause();
            } else if (CmdsTOP.equals(cmd)) {
                pause();
                seek(0);
            } else if (Mediaappwidgetprovider.CMDAPPWIDGETUPDATE.equals(cmd)) {
                // Someone asked us to refresh a set of specific widgets,probably
                // because they were just added.
                int[] appWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
                mappwidgetprovider.performUpdate(mediaplaybackService.this,appWidgetIds);
            }
        }
    };


通过分析可以得出要暂停音乐可以有两种方法,一种是直接发送cmd,另外一种是发送action。

如下暂停音乐播放代码:

复制代码 代码如下:

 private void pauseMusic() {
  Intent freshIntent = new Intent();
  freshIntent.setAction("com.android.music.musicservicecommand.pause");
  freshIntent.putExtra("command","pause");
  sendbroadcast(freshIntent);
 }

Android音乐播放器实践 -- Hide音乐播放器1.0版

Android音乐播放器实践 -- Hide音乐播放器1.0版

Hide音乐播放器

感谢:ZDepthShadow
播放器的素材是从『乐乐音乐』里面提取的。
LOGO是从Google上搜索的,如果造成不必要的麻烦请告知。

1.0版主要特点

  • 摇一摇进入播放器

  • 下拉展开新视图(扫描音乐)

  • 音乐列表放大的动画

  • 进入页面的圆形动画

  • 滑动删除音乐

  • 更换主题颜色

  • 自定义的SwitchButton

  • 播放页面的模糊背景

  • 带指示器的自定义SeekBar

  • 通知栏显示音乐信息与关闭播放器


代码地址:点击这里

APK下载:APK下载


截图

image image image image image image image image image image image image image


Delphi 音乐播放器系列[频谱、歌词、打开文件、播放进度]

Delphi 音乐播放器系列[频谱、歌词、打开文件、播放进度]

总结

以上是小编为你收集整理的Delphi 音乐播放器系列[频谱、歌词、打开文件、播放进度]全部内容。

如果觉得小编网站内容还不错,欢迎将小编网站推荐给好友。

关于JS实现网页手机音乐播放器歌词同步播放功能代码js音乐播放器显示歌词的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于Android实现音乐播放器歌词显示效果、android暂停或停止其他音乐播放器的播放实现代码、Android音乐播放器实践 -- Hide音乐播放器1.0版、Delphi 音乐播放器系列[频谱、歌词、打开文件、播放进度]的相关知识,请在本站寻找。

本文标签:

上一篇CSS和JS的加载和执行详解(css和js的加载和执行详解区别)

下一篇Angularjs过滤器完成排序功能实例详解(angularjs 过滤器)