简单的音乐播放器(上一曲,下一曲,暂停/播放,自动播放下一曲)

public class MainActivity extends AppCompatActivity implements View.OnClickListener, SeekBar.OnSeekBarChangeListener, MediaPlayer.OnCompletionListener {

    private MediaPlayer mediaPlayer;//播放音频的
    private Button mPreviousBtn;
    private Button mPlayBtn;
    private Button mNextBtn;
    private ListView mListView;
    private List<Song> list;
    private MyAdapter adapter;
    private SeekBar mSeekBar;
    private TextView mCurrentTimeTv;
    private TextView mTotalTimeTv;
    // 记录当前播放歌曲的位置
    private int mCurrentPosition;

    private Handler mHandler=new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message message) {
            // 展示给进度条和当前时间
            int progress = mediaPlayer.getCurrentPosition();
            mSeekBar.setProgress(progress);
            mCurrentTimeTv.setText(parseTime(progress));
            // 继续定时发送数据
            updateProgress();
            return true;
        }
    });



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mediaPlayer = new MediaPlayer();
        mPreviousBtn= (Button) findViewById(R.id.mPreviousBtn);
        mPlayBtn= (Button) findViewById(R.id.mPlayBtn);
        mNextBtn= (Button) findViewById(R.id.mNextBtn);
        mCurrentTimeTv= (TextView) findViewById(R.id.current_time_tv);
        mTotalTimeTv= (TextView) findViewById(R.id.total_time_tv);
        mSeekBar= (SeekBar) findViewById(R.id.seek_bar);
        mSeekBar.setOnSeekBarChangeListener(this);
        mPreviousBtn.setOnClickListener(this);
        mPlayBtn.setOnClickListener(this);
        mNextBtn.setOnClickListener(this);
        initView();
    }

    /**
     * 初始化view
     */
    private void initView() {
        mListView = (ListView) findViewById(R.id.main_listview);
        list = new ArrayList<>();
        //把扫描到的音乐赋值给list
        list = MusicUtils.getMusicData(this);
        adapter = new MyAdapter(this,list);
        mListView.setAdapter(adapter);
        mediaPlayer.setOnCompletionListener(this);
        mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                //创建一个播放音频的方法,把点击到的地址传过去
                //list.get(i).path这个就是歌曲的地址
//                String path = list.get(i).path;
//                Log.i("WDD",path);

                mCurrentPosition=i;
                changeMusic(mCurrentPosition);

//                play(list.get(i).path);
//                String singer = list.get(i).singer;//歌手
//                String song = list.get(i).song;//歌曲名称
//                int duration = list.get(i).duration;//歌曲长度

//                String time = MusicUtils.formatTime(duration);
//                String s=singer+"\n"+song+"\n"+time;
//                AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this);
//                    builder.setTitle("歌曲");
//                    builder.setMessage(s);
//                    builder.show();
            }
        });
    }
//    /**
//     * 播放音频的方法
//     */
//    private void play(String path) {
//        //播放之前要先把音频文件重置
//        try {
//            mediaPlayer.reset();
//            //调用方法传进去要播放的音频路径
//            mediaPlayer.setDataSource(path);
//            //异步准备音频资源
//            mediaPlayer.prepareAsync();
//            //调用mediaPlayer的监听方法,音频准备完毕会响应此方法
//            mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
//                @Override
//                public void onPrepared(MediaPlayer mediaPlayer) {
//                    mediaPlayer.start();//开始音频
//                }
//            });
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }


    @Override
    public void onClick(View view) {
        if (view.getId()==R.id.mPreviousBtn){//上一曲
            changeMusic(--mCurrentPosition);
        }else if (view.getId()==R.id.mPlayBtn){//暂停/播放
            // 首次点击播放按钮,默认播放第0首
            if (mediaPlayer==null){
                changeMusic(0);
            }else {
                if (mediaPlayer.isPlaying()){
                    mediaPlayer.pause();
                }else {
                    mediaPlayer.start();
                }
            }
        }else if (view.getId()==R.id.mNextBtn){// 下一首
            changeMusic(++mCurrentPosition);
        }
    }

    // 基本数据类型和String在方法调用中传递的是值
    // 其他数据类型在方法调用中传递的是引用

    //切歌
    private void changeMusic(int position){
        if (position<0){
            mCurrentPosition = position =list.size()-1;
        }else if (position>list.size()-1){
            mCurrentPosition = position=0;
        }

        if (mediaPlayer==null){
            mediaPlayer=new MediaPlayer();
        }

        try {
            // 切歌之前先重置,释放掉之前的资源
            mediaPlayer.reset();
            // 设置播放源
            mediaPlayer.setDataSource(list.get(position).path);
            // 开始播放前的准备工作,加载多媒体资源,获取相关信息
            mediaPlayer.prepare();

            // 开始播放
            mediaPlayer.start();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 切歌时重置进度条并展示歌曲时长
        mSeekBar.setProgress(0);
        mSeekBar.setMax(mediaPlayer.getDuration());
        mTotalTimeTv.setText(parseTime(mediaPlayer.getDuration()));

        updateProgress();
    }

    private void updateProgress() {
        // 使用Handler每间隔1s发送一次空消息,通知进度条更新
        Message msg = Message.obtain();// 获取一个现成的消息
        // 使用MediaPlayer获取当前播放时间除以总时间的进度
        int progress = mediaPlayer.getCurrentPosition();
        msg.arg1 = progress;
        mHandler.sendMessageDelayed(msg, INTERNAL_TIME);
    }

    private String parseTime(int oldTime) {
        SimpleDateFormat sdf = new SimpleDateFormat("mm:ss");// 时间格式
        String newTime = sdf.format(new Date(oldTime));
        return newTime;
    }

    private static final int INTERNAL_TIME = 1000;// 音乐进度间隔时间
    @Override
    public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
    }
    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
    }
    // 当手停止拖拽进度条时执行该方法
    // 获取拖拽进度
    // 将进度对应设置给MediaPlayer
    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        int progress = seekBar.getProgress();
        mediaPlayer.seekTo(progress);
    }

    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {
        changeMusic(++mCurrentPosition);
    }
}
**
 * 音乐工具类,
 */
public class MusicUtils {
    /**
     * 扫描系统里面的音频文件,返回一个list集合
     */
    public static List<Song> getMusicData(Context context) {
        List<Song> list = new ArrayList<Song>();
        // 媒体库查询语句(写一个工具类MusicUtils)
        Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null,
                null, MediaStore.Audio.AudioColumns.IS_MUSIC);
        if (cursor != null) {
            while (cursor.moveToNext()) {
                Song song = new Song();
                song.song = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME));
                song.singer = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
                song.path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
                song.duration = cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));
                song.size = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.SIZE));
                if (song.size > 1000 * 800) {
                    // 注释部分是切割标题,分离出歌曲名和歌手 (本地媒体库读取的歌曲信息不规范)
                    if (song.song.contains("-")) {
                        String[] str = song.song.split("-");
                        song.singer = str[0];
                        song.song = str[1];
                    }
                    list.add(song);
                }
            }
            // 释放资源
            cursor.close();
        }
        return list;
    }

    /**
     * 定义一个方法用来格式化获取到的时间
     */
    public static String formatTime(int time) {
        if (time / 1000 % 60 < 10) {
            return time / 1000 / 60 + ":0" + time / 1000 % 60;

        } else {
            return time / 1000 / 60 + ":" + time / 1000 % 60;
        }

    }
}

  

package com.example.lenovo.yinyuekao2;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import java.util.List;

public class MyAdapter extends BaseAdapter {
    private Context context;
    private List<Song> list;

    public MyAdapter(MainActivity mainActivity, List<Song> list) {
        this.context = mainActivity;
        this.list = list;

    }

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int i) {
        return list.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(final int i, View view, ViewGroup viewGroup) {
        ViewHolder holder = null;
        if (view == null) {
            holder = new ViewHolder();
            //引入布局
            view = View.inflate(context, R.layout.item_music_listview, null);
            //实例化对象
            holder.song = (TextView) view.findViewById(R.id.item_mymusic_song);
            holder.singer = (TextView) view.findViewById(R.id.item_mymusic_singer);
            holder.duration = (TextView) view.findViewById(R.id.item_mymusic_duration);
            holder.position = (TextView) view.findViewById(R.id.item_mymusic_postion);
            view.setTag(holder);
        } else {
            holder = (ViewHolder) view.getTag();
        }
        //给控件赋值
        holder.song.setText(list.get(i).song.toString());
        holder.singer.setText(list.get(i).singer.toString());
        //时间需要转换一下
        int duration = list.get(i).duration;
        String time = MusicUtils.formatTime(duration);
        holder.duration.setText(time);
        holder.position.setText(i+1+"");

        return view;
    }
    class ViewHolder{
        TextView song;//歌曲名
        TextView singer;//歌手
        TextView duration;//时长
        TextView position;//序号
        String parh;//地址
    }

}

  

package com.example.lenovo.yinyuekao2;

/**
 * Created by LENOVO on 2017/11/7.
 */

/**
 * Created by user on 2016/6/24.
 * 放置音乐
 */
public class Song {
    /**
     * 歌手
     */
    public String singer;
    /**
     * 歌曲名
     */
    public String song;
    /**
     * 歌曲的地址
     */
    public String path;
    /**
     * 歌曲长度
     */
    public int duration;
    /**
     * 歌曲的大小
     */
    public long size;
}
<?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:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.lenovo.yinyuekao2.MainActivity">

    <LinearLayout
        android:orientation="horizontal"
        android:id="@+id/main_textview"
        android:layout_width="match_parent"
        android:layout_height="40dp">
        <Button
            android:id="@+id/mPreviousBtn"
            android:text="上一曲"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent" />
        <Button
            android:id="@+id/mPlayBtn"
            android:text="播放/暂停"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent" />
        <Button
            android:id="@+id/mNextBtn"
            android:text="下一曲"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="match_parent" />
    </LinearLayout>

    <RelativeLayout
        android:id="@+id/main_textview1"
        android:layout_below="@+id/main_textview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/current_time_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="当前时间"/>

        <TextView
            android:id="@+id/total_time_tv"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:text="全部时间"/>

        <SeekBar
            android:id="@+id/seek_bar"
            style="?android:progressBarStyleHorizontal"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:layout_toLeftOf="@id/total_time_tv"
            android:layout_toRightOf="@id/current_time_tv"/>

    </RelativeLayout>

    <ListView
        android:id="@+id/main_listview"
        android:layout_below="@+id/main_textview1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>


</RelativeLayout>

  

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="110dp"
    android:orientation="horizontal"
    android:gravity="center_vertical"
    android:padding="5dp">
    <TextView
        android:id="@+id/item_mymusic_postion"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:text="1"
        android:gravity="center"
        android:textColor="#0d0c0c"
        android:textSize="18sp" />

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="20dp"
        >

        <TextView
            android:id="@+id/item_mymusic_song"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="歌曲名"
            android:textColor="#0d0c0c"
            android:textSize="20dp" />


        <TextView
            android:id="@+id/item_mymusic_singer"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/item_mymusic_song"
            android:text="歌手"
            android:textColor="#0d0c0c"
            android:textSize="15sp" />

        <TextView
            android:id="@+id/item_mymusic_duration"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/item_mymusic_song"
            android:layout_marginLeft="15dp"
            android:textColor="#0d0c0c"
            android:layout_toRightOf="@+id/item_mymusic_singer"
            android:text="时间"
            android:textSize="15sp" />
    </RelativeLayout>

</LinearLayout>

  记得加上权限

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

转载于:https://www.cnblogs.com/yudada/p/7846097.html

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用C语言实现音乐播放器的示例代码,包括上一曲、下一曲暂停播放等功能。请注意,这只是一个简单的示例,您需要根据实际情况进行修改和完善。 ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <pthread.h> #include <alsa/asoundlib.h> // 定义音频设备参数 #define CHANNELS 2 #define RATE 44100 #define PERIOD_SIZE 1024 #define BUFFER_SIZE (PERIOD_SIZE * 2 * CHANNELS) // 定义音乐文件路径 char *music_files[] = {"music1.mp3", "music2.mp3", "music3.mp3", NULL}; int current_file = 0; // 定义音频设备句柄和线程 snd_pcm_t *pcm_handle = NULL; pthread_t play_thread; // 定义播放状态和控制锁 int is_playing = 1; pthread_mutex_t play_mutex; // 定义函数原型 void *play_music(void *arg); void play_next(); void play_prev(); void play_pause(); void play_resume(); int main(int argc, char *argv[]) { // 初始化控制锁 pthread_mutex_init(&play_mutex, NULL); // 初始化音频设备 int err = 0; err = snd_pcm_open(&pcm_handle, "default", SND_PCM_STREAM_PLAYBACK, 0); if (err < 0) { printf("Unable to open PCM device: %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } snd_pcm_hw_params_t *hw_params; snd_pcm_hw_params_alloca(&hw_params); snd_pcm_hw_params_any(pcm_handle, hw_params); snd_pcm_hw_params_set_access(pcm_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); snd_pcm_hw_params_set_format(pcm_handle, hw_params, SND_PCM_FORMAT_S16_LE); snd_pcm_hw_params_set_channels(pcm_handle, hw_params, CHANNELS); unsigned int rate = RATE; snd_pcm_hw_params_set_rate_near(pcm_handle, hw_params, &rate, 0); snd_pcm_hw_params_set_period_size_near(pcm_handle, hw_params, (snd_pcm_uframes_t*)&PERIOD_SIZE, 0); snd_pcm_hw_params(pcm_handle, hw_params); // 创建播放线程 pthread_create(&play_thread, NULL, play_music, NULL); // 等待线程结束 pthread_join(play_thread, NULL); // 关闭音频设备和控制锁 snd_pcm_close(pcm_handle); pthread_mutex_destroy(&play_mutex); return 0; } void *play_music(void *arg) { while (music_files[current_file] != NULL) { // 加载音频文件 FILE *fp = fopen(music_files[current_file], "rb"); if (fp == NULL) { printf("Unable to open file: %s\n", music_files[current_file]); exit(EXIT_FAILURE); } // 初始化音频缓冲 char buffer[BUFFER_SIZE]; size_t count = 0; // 播放音频 while (is_playing && (count = fread(buffer, 1, sizeof(buffer), fp)) > 0) { // 暂停音频 pthread_mutex_lock(&play_mutex); while (!is_playing) { pthread_mutex_unlock(&play_mutex); usleep(100000); pthread_mutex_lock(&play_mutex); } pthread_mutex_unlock(&play_mutex); // 写入音频设备 int err = snd_pcm_writei(pcm_handle, buffer, count / 4); if (err == -EPIPE) { snd_pcm_prepare(pcm_handle); } else if (err < 0) { printf("Write error: %s\n", snd_strerror(err)); exit(EXIT_FAILURE); } } // 关闭音频文件 fclose(fp); // 播放一曲 if (music_files[current_file + 1] != NULL) { current_file++; } else { current_file = 0; } } return NULL; } void play_next() { // 切换到下一曲 if (music_files[current_file + 1] != NULL) { current_file++; } else { current_file = 0; } } void play_prev() { // 切换到上一曲 if (current_file > 0) { current_file--; } } void play_pause() { // 暂停播放 pthread_mutex_lock(&play_mutex); is_playing = 0; pthread_mutex_unlock(&play_mutex); } void play_resume() { // 恢复播放 pthread_mutex_lock(&play_mutex); is_playing = 1; pthread_mutex_unlock(&play_mutex); } ``` 在上述代码中,我们使用了ALSA库来初始化音频设备,并创建了一个线程来播放音乐文件。同时,我们还定义了上一曲、下一曲暂停播放等功能,使用控制锁来实现线程间的同步。请注意,上述代码只是一个示例,您需要根据具体情况进行修改和完善。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值