【问题标题】:Play list<byte[]> audio files from SQLite database从 SQLite 数据库播放列表<byte[]> 音频文件
【发布时间】:2018-02-05 09:47:13
【问题描述】:

我有一个以 BLOB 格式保存的音频数据表。我想播放音频文件,但从数据库调用方法时遇到问题。

这是我的 DatabaseAccess.java

    public List<byte[]> getAudio(long i) {
    List<byte[]> list = new ArrayList<>();
    File file;
    FileOutputStream fos;

    byte[] byteaudio = null;
    String selectAudio = "SELECT VocabAudio FROM Vocab WHERE VocabTopic =" + i;
    Cursor c = database.rawQuery(selectAudio, null);
    if(c.moveToFirst())
        do{
            byteaudio = c.getBlob(c.getColumnIndex("VocabAudio"));

            try{
                file = File.createTempFile("audio", "audio");
                fos = new FileOutputStream(file);
                fos.write(byteaudio);
                fos.close();

            }catch (IOException e){
                e.printStackTrace();
            }

        }while(c.moveToNext());

    return list;
}

这是我的活动类,我想在其中调用我的 getAudio() 方法。它说它找不到符号变量文件(来自 Uri.fromFile(file))。

    public void startSlides() {

    timer = new Timer();
    timer.scheduleAtFixedRate(new TimerTask() {

        public void run() {
            runOnUiThread(new Runnable() {
                public void run() {

                    Intent intent = getIntent();
                    long topicId = intent.getLongExtra("SelectedTopicId", 0);

                    databaseAccess.open();

                    List<byte[]> audio = databaseAccess.getAudio(topicId);

                    mp= MediaPlayer.create(Choice.this,Uri.fromFile(file));
                    i++;
                    mp.start();


                    databaseAccess.close();

                    if (j == vocab.size()+1) {
                        timer.cancel();
                    }
                }
            });
        }

    }, 0, 1000;
}

有人知道我应该如何调用 getAudio() 方法吗?谢谢。

【问题讨论】:

  • 可怕的实践,用 BLOB 膨胀数据库!!
  • 为什么?为什么File.createTempFile 并使用您的 BLOB 内容编写它,而您可以将其保存在某个文件中,而只是将路径保存在您的数据库中?同意 ModularSynth 100%...
  • @ModularSynth 对不起。我是安卓新手。有什么建议我应该怎么做?
  • @pskink 有什么建议可以检索我的 byte[] 音频文件列表而不是使用 File.createTempFile?
  • 正如@pskink 建议的那样,只需存储文件的路径即可。更清洁、更快捷。

标签: android sqlite audio android-sqlite android-mediaplayer


【解决方案1】:

您没有向list 添加任何内容,您只是将字节写入文件,另一件事是file 在另一种方法中,您将无法从您的活动中看到该引用。

而不是写入文件(在 getAutdio 中)将字节添加到列表中并返回它。

现在您可以从列表中播放音频或写入文件然后播放音频。

您的代码可能如下所示:

public List<byte[]> getAudio(long i) {
    List<byte[]> list = new ArrayList<>();

    byte[] byteaudio = null;
    String selectAudio = "SELECT VocabAudio FROM Vocab WHERE VocabTopic =" + i;
    Cursor c = database.rawQuery(selectAudio, null);
    if(c.moveToFirst())
    do{
        byteaudio = c.getBlob(c.getColumnIndex("VocabAudio"));
        list.add(byteaudio);
    }while(c.moveToNext());

    return list;
}

为了播放,您可以在文件中写入byte[] 创建MediaPlayer 参考this answer这只是一个概念,你可能需要稍微改变一下,或者使用最新的代码来使用MediaPlayer

public void run() {

    Intent intent = getIntent();
    long topicId = intent.getLongExtra("SelectedTopicId", 0);

    databaseAccess.open();
    List<byte[]> audio = databaseAccess.getAudio(topicId);
    databaseAccess.close();

    for(byte[] track : audio){
        playMp3(track);
    }//for loop

    if (j == vocab.size()+1) {
        timer.cancel();
    }
}

现在:由于您主要使用文件(播放媒体)并且如上面 cmets 建议的那样,您可以存储文件名和路径(如细绳) 然后您可以立即从数据库中检索文件名并启动媒体播放器

编辑:要逐个播放文件,您可能需要设置List&lt;byte[]&gt; audio 类范围,并调用playMp3(audio.get(index)); 其中index 是一个整数,每次播放时都会增加文件(但注意不要检查

类范围:

private List<byte[]> audio;
private int index =0;

然后点击播放按钮:

@Override
public void onClick(View view){
    if(index >= audio.size()){
        index = 0; // back to first track ?
    }
    playMp3(audio.get(index));
    ++index;
}

【讨论】:

  • 我现在可以播放音频但是它会产生多种声音,如果我想一个一个播放音频怎么办?我需要使用其他方法而不是 for 循环吗?
  • @chernting 是的,检查我的答案(编辑)
猜你喜欢
  • 1970-01-01
  • 2018-09-05
  • 1970-01-01
  • 1970-01-01
  • 2021-10-06
  • 2012-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多