从c#服务器流MP3到Android
本文关键字:Android MP3 服务器 | 更新日期: 2023-09-27 18:01:50
我已经建立了一个c#服务器,目前通过TCP提供一个测试mp3文件。发送文件的代码如下
public void RunStreamer()
{
log.MakeLog("Starting streamer");
Run = true;
//Need to look into how to thread this to not block the main window
TcpListener listen = new TcpListener(localAddr, _port);
listen.Start(); //startlistening to client requests
//blocks until a client request comes in
for (; ; )
{
Socket socket = listen.AcceptSocket();
if (socket.Connected)
{
SendFileToClient(socket);
socket.Disconnect(false);
}
}
}
void SendFileToClient(Socket socket)
{
log.MakeLog("Connection made");
NetworkStream netStream = new NetworkStream(socket);
StreamWriter writer = new StreamWriter(netStream);
//Todo - set specfified file - this file just for test
FileStream filestream = File.Open(@"C:'MusicTest'Test.mp3", FileMode.Open, FileAccess.Read, FileShare.Read);
filestream.CopyTo(netStream);
netStream.Flush();
netStream.Close();
}
在我的测试android设置中,我正在呼叫服务器上的一个按钮点击:
public void btngo_click(View v)
{
final TcpClient client = new TcpClient();
new Thread(new Runnable(){
@Override
public void run() {
final MediaPlayer mediaPlayer = new MediaPlayer();
client.GetStream();
runOnUiThread(new Runnable(){
public void run()
{
int length = client.GetLength();
if(length > 0)
{
byte[] result = client.GetResult();
try {
// create temp file that will hold byte array
File tempMp3 = File.createTempFile("test", "mp3", getCacheDir());
tempMp3.deleteOnExit();
FileOutputStream fos = new FileOutputStream(tempMp3);
fos.write(result);
fos.close();
mediaPlayer.reset();
FileInputStream fis = new FileInputStream(tempMp3);
mediaPlayer.setDataSource(fis.getFD());
mediaPlayer.prepare();
mediaPlayer.start();
} catch (IOException ex) {
String s = ex.toString();
ex.printStackTrace();
}
}
}
});
}
}).start();
}
流被TcpClient类接收,如下所示:
public class TcpClient {
public final static String SERVER_ADDRESS = "127.0.0.1";
public final static int SERVER_PORT = 65000;
public String TotalResult;
public int Length;
byte[] result = new byte[21000000];
public TcpClient()
{
}
public int GetLength()
{
return Length;
}
public byte[] GetResult()
{
return result;
}
public void GetStream()
{
try
{
final Socket socket = new Socket("192.0.0.5", 85000);
final InputStream input = new BufferedInputStream(socket.getInputStream());
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nread;
while((nread = input.read(result, 0, result.length)) != -1)
{
buffer.write(result, 0, nread);
}
buffer.flush();
//input.read(result);
Length = result.length;
input.close();
socket.close();
} catch (UnknownHostException e) {
String exc = e.getMessage();
e.printStackTrace();
} catch (IOException e) {
String exc2 = e.getMessage();
e.printStackTrace();
}
}
}
为所有的代码道歉,这是我的问题。
我正在接收流。创建临时MP3文件并启动媒体播放器。然后我只得到测试MP3文件的一小段(这是一首完整的歌曲)。它也有一点跳跃。长度是不一样的,每次播放的歌曲的部分是不同的。
我如何以有序的方式接收完整的文件,以便它将提供歌曲的完整播放。
我已经尝试绕过这个,有一个想法,我需要告诉我的客户应该怀疑什么文件大小,然后执行一些循环,直到收到所有数据,尽管我不知道如何成功实现这一点,如果这是正确的解决方案。
任何关于我在哪里出错或我能做些什么来纠正的指针将非常感激!!
在这个问题上没有得到答案,我又挖了一下。有两件事是错的:首先,我没有将流的大小作为一个int大小的头文件包含在我的流中。我明白,对于较小的文件,这不会是一个问题,但随着文件大小的增长,有必要确保整个流已被接收。
这又引发了另一个问题。我以byte[]形式发送的int在Java中没有返回正确的值。原来Java使用sbytes -128到127范围,而不是byte。然后需要一些代码将其转换为int类型。然后我可以指示读取器读取传入具有预期流的实际大小的byte[]缓冲区=瞧,它工作了。MP3文件接收和播放正常。