android http server播放直播码流分析
2014-06-26 16:46
405 查看
android 下载码流到本地,然后开启http server 提供码流下载服务,client的http请求报文分析:
1.http service 从服务获取ts码流切片,并保持到本地的过程:(推测,有待确认)
比如提供http://127.0.0.1:9906/12345.ts URL直播下载。
下载服务器的ts码流切片,写到12345.ts文件中。
估计是一个循环的文件,写到一定的大小,把前面的部分用新的ts流覆盖。用虚拟的文件来管理,虚拟文件的大小不断在增加,不断提供虚拟文件position靠后的ts内容给client。
我之前做的PVR就是用这种原理来做。
2. client 通过http server获取ts流的过程:
http request 头中的Range 字段为 0-,意思是获取整个文件大小。
http response头没有反馈返回的文件大小,就不断地将文件发送至client,在同一个http 长连接中发送ts流给client
GET /12345.ts HTTP/1.1
Host: 10.69.19.220:9906
User-Agent: VLC/2.1.3 LibVLC/2.1.3
Range: bytes=0-
Connection: close
Icy-MetaData: 1
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: no-cache
Content-Type: application/octet-stream
Date: Thu, 26 Jun 2014 07:28:09 GMT
Server: Microsoft-IIS/5.0
G......}..P:....@sEJ.............2unL.&.=..,EZ.T#..
*....../M...tzz.P....b..@..t.1....#u...:.G......v.....C/H..N.HI..U...q.
以下转自:/article/1363058.html
Android MediaPlayer与Http Proxy结合之基础篇
本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处!
最近半年都忙着Android TV项目,在春节假期才有时间写点东西。先在这里给大家拜个年,祝大家龙年快乐...
直接进入主题:本文将会教大家如何实现一个简单的代理服务器(仅支持Http Get),与Android的MediaPlayer结合,从而可以扩展出“播放 防盗链的媒体文件”,“边播放边保存”等的功能。
本文的代码可以到这里下载:http://download.csdn.net/detail/hellogv/4047134,代码分为两个工程:
J2SE工程:HttpGetProxy,在PC上实现简单的代理服务器,核心类是HttpGetProxy.java,非常容易使用,这里就不唠叨了直接贴出运行效果图:
Android工程:本文重点,必须唠叨一下。MediaPlayer播放网络音频(/article/1363064.html)与HttpGetProxy.java结合,通过代理服务器播放网络音频。
接下来贴出HttpGetProxy.java的原理图:
接下来贴出HttpGetProxy.java的源码:
通过RemoteSocket的out_remoteSocket可以访问防盗链资源,HttpGetProxy通过2个线程来实现转发,可以在两个线程内实现保存的功能。
[java] view
plaincopyprint?
<span style="font-family:Comic Sans MS;font-size:18px;">package com.musicplayer;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import android.util.Log;
public class HttpGetProxy {
final private String LOCAL_IP_ADDRESS = "127.0.0.1";
final private int HTTP_PORT = 80;
private ServerSocket localServer = null;
private Socket localSocket = null;
private Socket remoteSocket = null;
private String remoteIPAddress;
private InputStream in_remoteSocket;
private OutputStream out_remoteSocket;
private InputStream in_localSocket;
private OutputStream out_localSocket;
private interface OnFinishListener {
void onFinishListener();
}
public HttpGetProxy(int localport) {
// --------建立代理中转服务器-----------//
try {
localServer = new ServerSocket(localport, 1,
InetAddress.getByName(LOCAL_IP_ADDRESS));
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 结束时,清除所有资源
*/
private OnFinishListener finishListener =new OnFinishListener(){
@Override
public void onFinishListener() {
System.out.println("..........release all..........");
Log.e("---->","..........release all..........");
try {
in_localSocket.close();
out_remoteSocket.close();
in_remoteSocket.close();
out_localSocket.close();
localSocket.close();
remoteSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
public void startProxy(String remoteIpAddr) throws IOException {
remoteIPAddress = remoteIpAddr;
SocketAddress address = new InetSocketAddress(remoteIPAddress,HTTP_PORT);
// --------连接目标服务器---------//
remoteSocket = new Socket();
remoteSocket.connect(address);
System.out.println("..........remote Server connected..........");
Log.e("---->","..........remote Server connected..........");
in_remoteSocket = remoteSocket.getInputStream();
out_remoteSocket = remoteSocket.getOutputStream();
System.out.println("..........init remote Server I/O..........");
/**
* 接收本地request,并转发到远程服务器
*/
new Thread() {
public void run() {
int bytes_read;
byte[] local_request = new byte[5120];
try {
// 本地Socket
localSocket = localServer.accept();
System.out.println("..........localSocket connected..........");
Log.e("---->","..........localSocket connected..........");
in_localSocket = localSocket.getInputStream();
out_localSocket = localSocket.getOutputStream();
System.out.println("..........init local Socket I/O..........");
Log.e("---->","..........init local Socket I/O..........");
String buffer = "";
while ((bytes_read = in_localSocket.read(local_request)) != -1) {
String str = new String(local_request);
System.out.println("localSocket " + str);
Log.e("localSocket---->",str);
buffer = buffer + str;
if (buffer.contains("GET")
&& buffer.contains("\r\n\r\n")) {
//---把request中的本地ip改为远程ip---//
buffer = buffer.replace(LOCAL_IP_ADDRESS,remoteIPAddress);
System.out.println("已经替换IP");
out_remoteSocket.write(buffer.getBytes());
out_remoteSocket.flush();
continue;
} else{
out_remoteSocket.write(buffer.getBytes());
out_remoteSocket.flush();
}
}
System.out.println("..........local finish receive...........");
Log.e("---->","..........local finish receive..........");
finishListener.onFinishListener();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
/**
* 接收远程服务器reply,并转发到本地客户端
*/
new Thread() {
public void run() {
int bytes_read;
byte[] remote_reply = new byte[5120];
try {
System.out.println("..........remote start to receive...........");
Log.e("---->","..........remote start to receive..........");
while ((bytes_read = in_remoteSocket.read(remote_reply)) != -1) {
//System.out.println("remoteSocket " + remote_reply.length);
//System.out.println("remoteSocket " + new String(remote_reply));
out_localSocket.write(remote_reply, 0, bytes_read);
out_localSocket.flush();
}
System.out.println("..........remote finish receive...........");
Log.e("---->","..........remote finish receive..........");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
}
</span>
1.http service 从服务获取ts码流切片,并保持到本地的过程:(推测,有待确认)
比如提供http://127.0.0.1:9906/12345.ts URL直播下载。
下载服务器的ts码流切片,写到12345.ts文件中。
估计是一个循环的文件,写到一定的大小,把前面的部分用新的ts流覆盖。用虚拟的文件来管理,虚拟文件的大小不断在增加,不断提供虚拟文件position靠后的ts内容给client。
我之前做的PVR就是用这种原理来做。
2. client 通过http server获取ts流的过程:
http request 头中的Range 字段为 0-,意思是获取整个文件大小。
http response头没有反馈返回的文件大小,就不断地将文件发送至client,在同一个http 长连接中发送ts流给client
GET /12345.ts HTTP/1.1
Host: 10.69.19.220:9906
User-Agent: VLC/2.1.3 LibVLC/2.1.3
Range: bytes=0-
Connection: close
Icy-MetaData: 1
HTTP/1.1 200 OK
Accept-Ranges: bytes
Cache-Control: no-cache
Content-Type: application/octet-stream
Date: Thu, 26 Jun 2014 07:28:09 GMT
Server: Microsoft-IIS/5.0
G......}..P:....@sEJ.............2unL.&.=..,EZ.T#..
*....../M...tzz.P....b..@..t.1....#u...:.G......v.....C/H..N.HI..U...q.
以下转自:/article/1363058.html
Android MediaPlayer与Http Proxy结合之基础篇
本文来自http://blog.csdn.net/hellogv/ ,引用必须注明出处!
最近半年都忙着Android TV项目,在春节假期才有时间写点东西。先在这里给大家拜个年,祝大家龙年快乐...
直接进入主题:本文将会教大家如何实现一个简单的代理服务器(仅支持Http Get),与Android的MediaPlayer结合,从而可以扩展出“播放 防盗链的媒体文件”,“边播放边保存”等的功能。
本文的代码可以到这里下载:http://download.csdn.net/detail/hellogv/4047134,代码分为两个工程:
J2SE工程:HttpGetProxy,在PC上实现简单的代理服务器,核心类是HttpGetProxy.java,非常容易使用,这里就不唠叨了直接贴出运行效果图:
Android工程:本文重点,必须唠叨一下。MediaPlayer播放网络音频(/article/1363064.html)与HttpGetProxy.java结合,通过代理服务器播放网络音频。
接下来贴出HttpGetProxy.java的原理图:
接下来贴出HttpGetProxy.java的源码:
通过RemoteSocket的out_remoteSocket可以访问防盗链资源,HttpGetProxy通过2个线程来实现转发,可以在两个线程内实现保存的功能。
[java] view
plaincopyprint?
<span style="font-family:Comic Sans MS;font-size:18px;">package com.musicplayer;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import android.util.Log;
public class HttpGetProxy {
final private String LOCAL_IP_ADDRESS = "127.0.0.1";
final private int HTTP_PORT = 80;
private ServerSocket localServer = null;
private Socket localSocket = null;
private Socket remoteSocket = null;
private String remoteIPAddress;
private InputStream in_remoteSocket;
private OutputStream out_remoteSocket;
private InputStream in_localSocket;
private OutputStream out_localSocket;
private interface OnFinishListener {
void onFinishListener();
}
public HttpGetProxy(int localport) {
// --------建立代理中转服务器-----------//
try {
localServer = new ServerSocket(localport, 1,
InetAddress.getByName(LOCAL_IP_ADDRESS));
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 结束时,清除所有资源
*/
private OnFinishListener finishListener =new OnFinishListener(){
@Override
public void onFinishListener() {
System.out.println("..........release all..........");
Log.e("---->","..........release all..........");
try {
in_localSocket.close();
out_remoteSocket.close();
in_remoteSocket.close();
out_localSocket.close();
localSocket.close();
remoteSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
public void startProxy(String remoteIpAddr) throws IOException {
remoteIPAddress = remoteIpAddr;
SocketAddress address = new InetSocketAddress(remoteIPAddress,HTTP_PORT);
// --------连接目标服务器---------//
remoteSocket = new Socket();
remoteSocket.connect(address);
System.out.println("..........remote Server connected..........");
Log.e("---->","..........remote Server connected..........");
in_remoteSocket = remoteSocket.getInputStream();
out_remoteSocket = remoteSocket.getOutputStream();
System.out.println("..........init remote Server I/O..........");
/**
* 接收本地request,并转发到远程服务器
*/
new Thread() {
public void run() {
int bytes_read;
byte[] local_request = new byte[5120];
try {
// 本地Socket
localSocket = localServer.accept();
System.out.println("..........localSocket connected..........");
Log.e("---->","..........localSocket connected..........");
in_localSocket = localSocket.getInputStream();
out_localSocket = localSocket.getOutputStream();
System.out.println("..........init local Socket I/O..........");
Log.e("---->","..........init local Socket I/O..........");
String buffer = "";
while ((bytes_read = in_localSocket.read(local_request)) != -1) {
String str = new String(local_request);
System.out.println("localSocket " + str);
Log.e("localSocket---->",str);
buffer = buffer + str;
if (buffer.contains("GET")
&& buffer.contains("\r\n\r\n")) {
//---把request中的本地ip改为远程ip---//
buffer = buffer.replace(LOCAL_IP_ADDRESS,remoteIPAddress);
System.out.println("已经替换IP");
out_remoteSocket.write(buffer.getBytes());
out_remoteSocket.flush();
continue;
} else{
out_remoteSocket.write(buffer.getBytes());
out_remoteSocket.flush();
}
}
System.out.println("..........local finish receive...........");
Log.e("---->","..........local finish receive..........");
finishListener.onFinishListener();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
/**
* 接收远程服务器reply,并转发到本地客户端
*/
new Thread() {
public void run() {
int bytes_read;
byte[] remote_reply = new byte[5120];
try {
System.out.println("..........remote start to receive...........");
Log.e("---->","..........remote start to receive..........");
while ((bytes_read = in_remoteSocket.read(remote_reply)) != -1) {
//System.out.println("remoteSocket " + remote_reply.length);
//System.out.println("remoteSocket " + new String(remote_reply));
out_localSocket.write(remote_reply, 0, bytes_read);
out_localSocket.flush();
}
System.out.println("..........remote finish receive...........");
Log.e("---->","..........remote finish receive..........");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
}
</span>
相关文章推荐
- 基于feng streaming server 搭建Android直播测试平台
- Android 播放mp3 tag乱码分析之java 篇
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析(3)
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
- Android apache DefaultHttpClient 和 java net HttpURLConnection 简单分析
- [总结]Server Application Error(IIS5 HTTP500)内部错误分析及解决办法
- [Binder.3] Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
- 使用libevent实现最简单的android http-server
- Android 播放mp3 tag乱码分析之jni 篇
- android stagefright 播放MP3音频 打印信息分析
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析(2)
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析(3)
- 通过tcpdump/wireshark工具分析Android平台上现有的直播技术
- android stagefright 播放MP4视频 打印信息分析
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析(1) 推荐
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
- 基于feng streaming server 搭建Android直播测试平台