![](/img/trans.png)
[英]Android, get text from url works fine in eclipse but not on device
[英]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.