簡體   English   中英

如何讓 Android MediaPlayer 運行我的 http url? 與其他網址一起工作就好了

[英]How I get the Android MediaPlayer running my http url? With other urls it works just fine

所以我想構建一個從我的后端服務器流式傳輸音樂的應用程序。 為此,我創建了一個帶有 MongoDB 的 Node JS Express API。 然后我有一個 url 像這樣: http://192.168.178.26:3000/stream?id=5dd5065f3b9a2a22149fdb09&format=mp3

當我在我的瀏覽器(Opera)中輸入這個 url 時,它會像預期的那樣 stream 音樂。 Postman 也可以使用。

然后我用 Android Studio 為 Android 編寫了一個應用程序,該應用程序從給定的 url 流式傳輸音樂。 當我嘗試這個 url: https://www.ssaurel.com/tmp/mymusic.mp3時,這工作正常,但不是我的。 當我用我的 url 嘗試這個時,MediaPlayer 在准備時失敗了。 錯誤如下: Prepare failed.: status=0x1 我搜索了這個錯誤,發現它意味着unknown Error

我的后端代碼:

const express = require('express');
const dbHandler = require('./src/dbHandler/dbHandler.js');
const fs = require('fs');
const app = express();

app.get('/stream', (req, res) => {
    console.log(`Got stream request from ${req.ip}...`);
    dbHandler.getFilePath(req.query.id, req.query.format).then((path) => {
        let stat = fs.statSync(path);
        res.set({
            'Content-Type': 'audio/mpeg',
            'Content-Length': stat.size,
            'Accept-Ranges': 'bytes',
            'Cache-Control': 'max-age=3600'
        });
        fs.createReadStream(path).pipe(res);
    }).catch(err => {
        res.status(400).send(err)
    })
})

app.listen(3000, () => {
    console.log(`Server is listening at 3000...`);
    dbHandler.init();
})

如您所見,當服務器收到 stream 請求時將其打印出來。 dbHandler.getFilePath() - 方法只返回 mp3 位置的完整路徑,如下所示: D:/Music/song.mp3 當我用 postman 嘗試這個時,服務器收到一個請求並打印它。 然后 Postman 得到 stream ,我可以開始播放音樂了。

當我在我的智能手機上用我的瀏覽器嘗試這個時,它也可以工作。 所以我可以通過智能手機的瀏覽器而不是我的應用程序來播放音樂。

重要的是要注意,當我嘗試准備 MediaPlayer 時,服務器沒有收到請求。 因此,提交請求並沒有記錄到控制台。

這是我的應用程序的代碼:

package sharemusic.truerushhunt3r.de.sharemusic.frontend;

import android.media.AudioManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.Toast;

import java.io.IOException;

import sharemusic.truerushhunt3r.de.sharemusic.R;

public class MainActivity extends AppCompatActivity {

    //private GetHandler getHandler;
    private boolean isPlaying = false;
    private boolean initialStage = true;
    private MediaPlayer player;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //getHandler = new GetHandler();
        player = new MediaPlayer();
        player.setAudioStreamType(AudioManager.STREAM_MUSIC);

        ImageButton playButton = findViewById(R.id.playButton);
        playButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!isPlaying) {
                    Log.d("ShareMusic/Button", "Play pressed");
                    Toast.makeText(getApplicationContext(), "Play", Toast.LENGTH_SHORT).show();
                    if (initialStage) {
                        //new Player().execute("https://www.ssaurel.com/tmp/mymusic.mp3");
                        new Player().execute("http://192.168.178.26:3000/stream?id=5dd5065f3b9a2a22149fdb09&format=mp3");                    
                    } else {
                        if (!player.isPlaying()) {
                            player.start();
                        }
                    }
                    isPlaying = true;
                } else {
                    Log.d("ShareMusic/Button", "Pause pressed");
                    Toast.makeText(getApplicationContext(), "Pause", Toast.LENGTH_SHORT).show();
                    if (player.isPlaying()) {
                        player.pause();
                    }

                    isPlaying = false;
                }
            }
        });  
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (player != null) {
            player.reset();
            player.release();
            player = null;
        }
    }

    class Player extends AsyncTask<String, Void, Boolean> {
        @Override
        protected Boolean doInBackground(String... strings) {
            Boolean prepared = false;

            try {
                player.setDataSource(getApplicationContext(), Uri.parse(strings[0]));
                player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    @Override
                    public void onCompletion(MediaPlayer mp) {
                        initialStage = true;
                        isPlaying = false;
                        mp.stop();
                        mp.reset();
                    }
                });

                player.prepare();
                prepared = true;
            } catch(Exception e) {
                Log.e("ShareMusic", e.getMessage());
            }
            return prepared;
        }

        @Override
        protected void onPostExecute(Boolean aBoolean) {
            super.onPostExecute(aBoolean);
            if (aBoolean) {
                player.start();
                initialStage = false;
                isPlaying = false;
            } else {
                Toast.makeText(getApplicationContext(), "Failed to prepare", Toast.LENGTH_SHORT).show();
                initialStage = true;
                isPlaying = false;
            }
        }

    }
}

我的 url 的響應標頭:http://192.168.178.26:3000/stream?id=5dd5065f3b9a2a22149fdb09&format=mp3

工作 url 的響應標頭:https://www.ssaurel.com/tmp/mymusic.mp3

我認為這與 http 和 https 協議無關。 但我真的不知道現在該怎么辦。 android (mp3) btw 支持我的音樂文件。 我的后端錯了還是應用程序錯了? 我該如何解決這個問題?

當有什么不清楚的時候,請詢問。

Android API 等級:19及以上

設備:華為 P20 Lite

操作系統:9.1.0

好的,伙計們,我明白了! 看看這個網站 基本上,您必須編寫cleartextTrafficPermitted="true"而不是cleartextTrafficPermitted="false"才能使魔術發生。

所以我的結論是,媒體播放器不喜歡 http 連接,但喜歡 https。 但我不明白為什么它沒有告訴我這個......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM