连接 SDK:从 Android 将视频文件共享到 Apple TV
Connect SDK: Share Video file to Apple TV from Android
我使用 Connect SDK v v1.4.3 将 android 设备连接到 Apple TV
我可以通过自己的 WebServer(扩展 NanoHttpd)从我的设备共享音频和照片文件,但是当我尝试将 Vidio 文件共享到电视时,我看到警报 "downloading content fails" 但在日志中一切正常
05-15 22:49:54.764 31061-2326/com.example.sharemedia D/AirPlay﹕ [ 05-15 22:49:54.767 31061:31061 D/MediaHelper ]
onSuccess:::line:520:::VIDEO PLAY
我的方法
public void playVideo(String path) {
String videoPath = path;
// String videoPath = "http://10.0.1.66:8091/Download/Eminem%20-%20Guts%20Over%20Fear%20ft.%20Sia.mp4";
String mimeType = "video/" + FilenameUtils.getExtension(path);
Log.d("MediaHelper", "playVideo:::line:509:::" + mimeType);
String title = "title";
String description = "description";
String icon = "";
Log.d("MediaHelper", "playVideo:::line:515:::" + path);
mediaPlayer.playMedia(videoPath, mimeType, title, description, icon, true, new MediaPlayer.LaunchListener() {
public void onSuccess(MediaPlayer.MediaLaunchObject object) {
Log.d("MediaHelper", "onSuccess:::line:520:::" + "VIDEO PLAY");
launchSession = object.launchSession;
// testResponse = new TestResponseObject(true, TestResponseObject.SuccessCode, TestResponseObject.Play_Video);
mMediaControl = object.mediaControl;
mPlaylistControl = object.playlistControl;
stopUpdating();
enableMedia();
isPlaying = true;
}
@Override
public void onError(ServiceCommandError error) {
Log.d("MediaHelper", "onError:::line:534:::" + "Error playing Video");
if (launchSession != null) {
launchSession.close(null);
launchSession = null;
// testResponse = new TestResponseObject(false, error.getCode(), error.getMessage());
stopUpdating();
disableMedia();
isPlaying = isPlayingImage = false;
}
}
});
}
我也尝试把我的URL放到Connect-SDK-Android-API-Sampler但是问题没有解决
如果我在浏览器中打开我的 URL (Chrome) 视频正在播放。
网络服务器方法
@Override
public Response serve(IHTTPSession session) {
Method method = session.getMethod();
switch (method) {
case GET:
String path = session.getUri().replace(Utils.getIPAddress(true) + ":" + port, "");
//TODO refactoring
String type = FilenameUtils.getExtension(path);
String contentType = "";
if (type.equals("jpg") || type.equals("jpeg") || type.equals("png") || type.equals("gif") || type.equals("tiff"))
contentType = "image/";
else if (type.equals("mpeg") || type.equals("mp4") || type.equals("avi") || type.equals("quicktime"))
contentType = "video/";
else if (type.equals("mp3") || type.equals("wav") || type.equals("acc") || type.equals("aiff"))
contentType = "audio/";
else return new Response(Response.Status.BAD_REQUEST, NanoHTTPD.MIME_PLAINTEXT, "HTTPError: HTTP 8: BAD REQUEST 1");
contentType += type;
FileInputStream fis = null;
try {
fis = new FileInputStream(Environment.getExternalStorageDirectory() + path);
} catch (FileNotFoundException e) {
new Response(Response.Status.BAD_REQUEST, NanoHTTPD.MIME_PLAINTEXT, "HTTPError: HTTP 8: BAD REQUEST 2");
}
return new Response(Response.Status.OK, contentType, fis);
default:
return new Response(Response.Status.METHOD_NOT_ALLOWED, NanoHTTPD.MIME_PLAINTEXT, "HTTPError: HTTP 405: Method Not Allowed");
}
}
P.S。对不起我的英语。
问题出在回复中。
我将 "Content-Range" 和 "Content-Length" 添加到 Headers,并且视频流有效。
private FileInputStream fileInputStream;
@Override
public Response serve(IHTTPSession session) {
....
String range = session.getHeaders().get("range");
if (range != null)
return getVideoResponse(filePath, contentType, range);
else
.....
....
}
private Response getVideoResponse(String filePath, String mimeType, String rangeHdr) {
File file = new File(filePath);
String rangeValue = rangeHdr.trim().substring("bytes=".length());
long fileLength = file.length();
long start, end;
if (rangeValue.startsWith("-")) {
end = fileLength - 1;
start = fileLength - 1 - Long.parseLong(rangeValue.substring("-".length()));
} else {
String[] range = rangeValue.split("-");
start = Long.parseLong(range[0]);
end = range.length > 1 ? Long.parseLong(range[1])
: fileLength - 1;
}
if (end > fileLength - 1) {
end = fileLength - 1;
}
if (start <= end) {
long contentLength = end - start + 1;
try {
cleanupStream();
fileInputStream = new FileInputStream(file);
fileInputStream.skip(start);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Response response = new Response(Response.Status.PARTIAL_CONTENT, mimeType, fileInputStream);
response.addHeader("Content-Length", contentLength + "");
response.addHeader("Content-Range", "bytes " + start + "-" + end + "/" + fileLength);
return response;
} else {
return new Response(Response.Status.RANGE_NOT_SATISFIABLE, NanoHTTPD.MIME_PLAINTEXT, rangeHdr);
}
}
private voud cleanupStream() throws IOException {
if (fileInputStream != null)
fileInputStream.close();
}
我使用 Connect SDK v v1.4.3 将 android 设备连接到 Apple TV 我可以通过自己的 WebServer(扩展 NanoHttpd)从我的设备共享音频和照片文件,但是当我尝试将 Vidio 文件共享到电视时,我看到警报 "downloading content fails" 但在日志中一切正常
05-15 22:49:54.764 31061-2326/com.example.sharemedia D/AirPlay﹕ [ 05-15 22:49:54.767 31061:31061 D/MediaHelper ]
onSuccess:::line:520:::VIDEO PLAY
我的方法
public void playVideo(String path) {
String videoPath = path;
// String videoPath = "http://10.0.1.66:8091/Download/Eminem%20-%20Guts%20Over%20Fear%20ft.%20Sia.mp4";
String mimeType = "video/" + FilenameUtils.getExtension(path);
Log.d("MediaHelper", "playVideo:::line:509:::" + mimeType);
String title = "title";
String description = "description";
String icon = "";
Log.d("MediaHelper", "playVideo:::line:515:::" + path);
mediaPlayer.playMedia(videoPath, mimeType, title, description, icon, true, new MediaPlayer.LaunchListener() {
public void onSuccess(MediaPlayer.MediaLaunchObject object) {
Log.d("MediaHelper", "onSuccess:::line:520:::" + "VIDEO PLAY");
launchSession = object.launchSession;
// testResponse = new TestResponseObject(true, TestResponseObject.SuccessCode, TestResponseObject.Play_Video);
mMediaControl = object.mediaControl;
mPlaylistControl = object.playlistControl;
stopUpdating();
enableMedia();
isPlaying = true;
}
@Override
public void onError(ServiceCommandError error) {
Log.d("MediaHelper", "onError:::line:534:::" + "Error playing Video");
if (launchSession != null) {
launchSession.close(null);
launchSession = null;
// testResponse = new TestResponseObject(false, error.getCode(), error.getMessage());
stopUpdating();
disableMedia();
isPlaying = isPlayingImage = false;
}
}
});
}
我也尝试把我的URL放到Connect-SDK-Android-API-Sampler但是问题没有解决
如果我在浏览器中打开我的 URL (Chrome) 视频正在播放。
网络服务器方法
@Override
public Response serve(IHTTPSession session) {
Method method = session.getMethod();
switch (method) {
case GET:
String path = session.getUri().replace(Utils.getIPAddress(true) + ":" + port, "");
//TODO refactoring
String type = FilenameUtils.getExtension(path);
String contentType = "";
if (type.equals("jpg") || type.equals("jpeg") || type.equals("png") || type.equals("gif") || type.equals("tiff"))
contentType = "image/";
else if (type.equals("mpeg") || type.equals("mp4") || type.equals("avi") || type.equals("quicktime"))
contentType = "video/";
else if (type.equals("mp3") || type.equals("wav") || type.equals("acc") || type.equals("aiff"))
contentType = "audio/";
else return new Response(Response.Status.BAD_REQUEST, NanoHTTPD.MIME_PLAINTEXT, "HTTPError: HTTP 8: BAD REQUEST 1");
contentType += type;
FileInputStream fis = null;
try {
fis = new FileInputStream(Environment.getExternalStorageDirectory() + path);
} catch (FileNotFoundException e) {
new Response(Response.Status.BAD_REQUEST, NanoHTTPD.MIME_PLAINTEXT, "HTTPError: HTTP 8: BAD REQUEST 2");
}
return new Response(Response.Status.OK, contentType, fis);
default:
return new Response(Response.Status.METHOD_NOT_ALLOWED, NanoHTTPD.MIME_PLAINTEXT, "HTTPError: HTTP 405: Method Not Allowed");
}
}
P.S。对不起我的英语。
问题出在回复中。
我将 "Content-Range" 和 "Content-Length" 添加到 Headers,并且视频流有效。
private FileInputStream fileInputStream;
@Override
public Response serve(IHTTPSession session) {
....
String range = session.getHeaders().get("range");
if (range != null)
return getVideoResponse(filePath, contentType, range);
else
.....
....
}
private Response getVideoResponse(String filePath, String mimeType, String rangeHdr) {
File file = new File(filePath);
String rangeValue = rangeHdr.trim().substring("bytes=".length());
long fileLength = file.length();
long start, end;
if (rangeValue.startsWith("-")) {
end = fileLength - 1;
start = fileLength - 1 - Long.parseLong(rangeValue.substring("-".length()));
} else {
String[] range = rangeValue.split("-");
start = Long.parseLong(range[0]);
end = range.length > 1 ? Long.parseLong(range[1])
: fileLength - 1;
}
if (end > fileLength - 1) {
end = fileLength - 1;
}
if (start <= end) {
long contentLength = end - start + 1;
try {
cleanupStream();
fileInputStream = new FileInputStream(file);
fileInputStream.skip(start);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Response response = new Response(Response.Status.PARTIAL_CONTENT, mimeType, fileInputStream);
response.addHeader("Content-Length", contentLength + "");
response.addHeader("Content-Range", "bytes " + start + "-" + end + "/" + fileLength);
return response;
} else {
return new Response(Response.Status.RANGE_NOT_SATISFIABLE, NanoHTTPD.MIME_PLAINTEXT, rangeHdr);
}
}
private voud cleanupStream() throws IOException {
if (fileInputStream != null)
fileInputStream.close();
}