如何使用 NanoHTTPD 将图像发送到 Chromecast
How to send an image to Chromecast using NanoHTTPD
我想向 Chromecast 提供文件(例如图像)。我使用了 nanoHTTPD,所以我可以通过 url 访问内容,这是我用来获取 url:
的代码
private class WebServer extends NanoHTTPD {
public WebServer() {
super(8080);
}
@Override
public Response serve(String uri, Method method,
Map<String, String> header, Map<String, String> parameters,
Map<String, String> files) {
File rootDir = Environment.getExternalStorageDirectory();
File[] filesList = null;
String filepath = "";
if (uri.trim().isEmpty()) {
filesList = rootDir.listFiles();
} else {
filepath = uri.trim();
}
filesList = new File(filepath).listFiles();
String answer = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><title>sdcard0 - TECNO P5 - WiFi File Transfer Pro</title>";
if (new File(filepath).isDirectory()) {
for (File detailsOfFiles : filesList) {
answer += "<a href=\"" + detailsOfFiles.getAbsolutePath()
+ "\" alt = \"\">"
+ detailsOfFiles.getAbsolutePath() + "</a><br>";
}
} else {
}
answer += "</head></html>" + "uri: " + uri + " \nfiles " + files
+ " \nparameters " + parameters + " \nheader ";
return new NanoHTTPD.Response(answer);
}
}
这样我可以得到像“192.168.X.XX:8080/image.gif”这样的url。然后我为此创建一个常规 MediaInfo url:
private void startVideo() {
MediaMetadata mediaMetadata = new MediaMetadata( MediaMetadata.MEDIA_TYPE_PHOTO );
mediaMetadata.putString( MediaMetadata.KEY_TITLE, getString( R.string.titulo_video ) );
MediaInfo mediaInfo = new MediaInfo.Builder( getString( R.string.video_url ) )
.setContentType( getString( R.string.content_type_gif ) )
.setStreamType( MediaInfo.STREAM_TYPE_BUFFERED )
.setMetadata( mediaMetadata )
.build();
try {
mRemoteMediaPlayer.load( apiClient, mediaInfo, true )
.setResultCallback( new ResultCallback<RemoteMediaPlayer.MediaChannelResult>() {
@Override
public void onResult( RemoteMediaPlayer.MediaChannelResult mediaChannelResult ) {
if( mediaChannelResult.getStatus().isSuccess() ) {
mVideoIsLoaded = true;
mButton.setText( getString( R.string.pause_video ) );
}
}
} );
} catch( Exception e ) {
}
}
其中 <string name="video_url">http://192.168.1.38:8080/sdcard/logo_etsiit.gif</string>
是我之前得到的 url,但是当我尝试投射图像时没有任何反应。
是否可以直接将文件提供给 MediaInfo 而无需从网络浏览器复制和粘贴 url?
如果需要更多代码,请告诉我。
记录错误:
08-07 20:30:35.568 14669-14669/com.example.httpserver W/Httpd﹕ Web server initialized.
08-07 20:30:35.601 14669-14669/com.example.httpserver I/MediaRouter﹕ Found default route: MediaRouter.RouteInfo{ uniqueId=android/.support.v7.media.SystemMediaRouteProvider:DEFAULT_ROUTE, name=Teléfono, description=null, enabled=true, connecting=false, playbackType=0, playbackStream=3, volumeHandling=1, volume=3, volumeMax=15, presentationDisplayId=-1, extras=null, providerPackageName=android }
08-07 20:30:35.610 14669-14669/com.example.httpserver W/System.err﹕ java.net.BindException: bind failed: EADDRINUSE (Address already in use)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at libcore.io.IoBridge.bind(IoBridge.java:99)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:132)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at java.net.ServerSocket.bind(ServerSocket.java:335)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at java.net.ServerSocket.bind(ServerSocket.java:295)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at com.example.httpserver.NanoHTTPD.start(NanoHTTPD.java:142)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at com.example.httpserver.MainActivity.onResume(MainActivity.java:128)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1257)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.app.Activity.performResume(Activity.java:6076)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2975)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3017)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2392)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.app.ActivityThread.access0(ActivityThread.java:151)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:102)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.os.Looper.loop(Looper.java:135)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5254)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at java.lang.reflect.Method.invoke(Native Method)
08-07 20:30:35.612 14669-14669/com.example.httpserver W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:372)
08-07 20:30:35.612 14669-14669/com.example.httpserver W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
08-07 20:30:35.612 14669-14669/com.example.httpserver W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
08-07 20:30:35.612 14669-14669/com.example.httpserver W/System.err﹕ Caused by: android.system.ErrnoException: bind failed: EADDRINUSE (Address already in use)
08-07 20:30:35.612 14669-14669/com.example.httpserver W/System.err﹕ at libcore.io.Posix.bind(Native Method)
08-07 20:30:35.612 14669-14669/com.example.httpserver W/System.err﹕ at libcore.io.ForwardingOs.bind(ForwardingOs.java:56)
08-07 20:30:35.612 14669-14669/com.example.httpserver W/System.err﹕ at libcore.io.IoBridge.bind(IoBridge.java:97)
08-07 20:30:35.612 14669-14669/com.example.httpserver W/System.err﹕ ... 19 more
当我 select 来自网络浏览器的图像时,我只能看到:
uri: /sdcard/logo_etsiit.gif files {} parameters {} header
编辑:我用 WebServer class 解决了这个问题,现在我可以在我的网络浏览器中看到图像或 PDF selected
public class webserver extends NanoHTTPD {
FileInputStream fileInputStream;
public webserver(){
super(8080);
}
@Override
public Response serve(String uri, Method method, Map<String, String> header,Map<String, String> parameters, Map<String, String> files) {
String mediasend=getExtension(chosenFile);
FileInputStream fis = null;
try {
fis = new FileInputStream(Environment.getExternalStorageDirectory()
+ "/" + chosenFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return new NanoHTTPD.Response(etsiit.etsiitcast_def.NanoHTTPD.Response.Status.OK,mediasend,fis);
}
}
我也将这段代码添加到 onCreate:
//Get the ip of the device running NanoHTTPD server
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
ipdevice=String.format("http://%d.%d.%d.%d:8080",(ipAddress & 0xff),(ipAddress >> 8 & 0xff),(ipAddress >> 16 & 0xff),(ipAddress >> 24 & 0xff));
// start the webserver
mediaserver = new webserver();
try {
mediaserver.start();
} catch(IOException ioe) {
Log.d("Httpd", "The server could not start.");
}
我找到了问题的解决方案:我只需要将 MediaInfo mediaInfo = new MediaInfo.Builder( getString( R.string.video_url ) )
更改为 MediaInfo mediaInfo = new MediaInfo.Builder(ipdevice)
,其中 ipdevice
是我的 phone IP 地址(例如 http://192.168.1.40:8080).
我想向 Chromecast 提供文件(例如图像)。我使用了 nanoHTTPD,所以我可以通过 url 访问内容,这是我用来获取 url:
的代码private class WebServer extends NanoHTTPD {
public WebServer() {
super(8080);
}
@Override
public Response serve(String uri, Method method,
Map<String, String> header, Map<String, String> parameters,
Map<String, String> files) {
File rootDir = Environment.getExternalStorageDirectory();
File[] filesList = null;
String filepath = "";
if (uri.trim().isEmpty()) {
filesList = rootDir.listFiles();
} else {
filepath = uri.trim();
}
filesList = new File(filepath).listFiles();
String answer = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><title>sdcard0 - TECNO P5 - WiFi File Transfer Pro</title>";
if (new File(filepath).isDirectory()) {
for (File detailsOfFiles : filesList) {
answer += "<a href=\"" + detailsOfFiles.getAbsolutePath()
+ "\" alt = \"\">"
+ detailsOfFiles.getAbsolutePath() + "</a><br>";
}
} else {
}
answer += "</head></html>" + "uri: " + uri + " \nfiles " + files
+ " \nparameters " + parameters + " \nheader ";
return new NanoHTTPD.Response(answer);
}
}
这样我可以得到像“192.168.X.XX:8080/image.gif”这样的url。然后我为此创建一个常规 MediaInfo url:
private void startVideo() {
MediaMetadata mediaMetadata = new MediaMetadata( MediaMetadata.MEDIA_TYPE_PHOTO );
mediaMetadata.putString( MediaMetadata.KEY_TITLE, getString( R.string.titulo_video ) );
MediaInfo mediaInfo = new MediaInfo.Builder( getString( R.string.video_url ) )
.setContentType( getString( R.string.content_type_gif ) )
.setStreamType( MediaInfo.STREAM_TYPE_BUFFERED )
.setMetadata( mediaMetadata )
.build();
try {
mRemoteMediaPlayer.load( apiClient, mediaInfo, true )
.setResultCallback( new ResultCallback<RemoteMediaPlayer.MediaChannelResult>() {
@Override
public void onResult( RemoteMediaPlayer.MediaChannelResult mediaChannelResult ) {
if( mediaChannelResult.getStatus().isSuccess() ) {
mVideoIsLoaded = true;
mButton.setText( getString( R.string.pause_video ) );
}
}
} );
} catch( Exception e ) {
}
}
其中 <string name="video_url">http://192.168.1.38:8080/sdcard/logo_etsiit.gif</string>
是我之前得到的 url,但是当我尝试投射图像时没有任何反应。
是否可以直接将文件提供给 MediaInfo 而无需从网络浏览器复制和粘贴 url?
如果需要更多代码,请告诉我。
记录错误:
08-07 20:30:35.568 14669-14669/com.example.httpserver W/Httpd﹕ Web server initialized.
08-07 20:30:35.601 14669-14669/com.example.httpserver I/MediaRouter﹕ Found default route: MediaRouter.RouteInfo{ uniqueId=android/.support.v7.media.SystemMediaRouteProvider:DEFAULT_ROUTE, name=Teléfono, description=null, enabled=true, connecting=false, playbackType=0, playbackStream=3, volumeHandling=1, volume=3, volumeMax=15, presentationDisplayId=-1, extras=null, providerPackageName=android }
08-07 20:30:35.610 14669-14669/com.example.httpserver W/System.err﹕ java.net.BindException: bind failed: EADDRINUSE (Address already in use)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at libcore.io.IoBridge.bind(IoBridge.java:99)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:132)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at java.net.ServerSocket.bind(ServerSocket.java:335)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at java.net.ServerSocket.bind(ServerSocket.java:295)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at com.example.httpserver.NanoHTTPD.start(NanoHTTPD.java:142)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at com.example.httpserver.MainActivity.onResume(MainActivity.java:128)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1257)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.app.Activity.performResume(Activity.java:6076)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2975)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3017)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2392)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.app.ActivityThread.access0(ActivityThread.java:151)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1303)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:102)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.os.Looper.loop(Looper.java:135)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5254)
08-07 20:30:35.611 14669-14669/com.example.httpserver W/System.err﹕ at java.lang.reflect.Method.invoke(Native Method)
08-07 20:30:35.612 14669-14669/com.example.httpserver W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:372)
08-07 20:30:35.612 14669-14669/com.example.httpserver W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
08-07 20:30:35.612 14669-14669/com.example.httpserver W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
08-07 20:30:35.612 14669-14669/com.example.httpserver W/System.err﹕ Caused by: android.system.ErrnoException: bind failed: EADDRINUSE (Address already in use)
08-07 20:30:35.612 14669-14669/com.example.httpserver W/System.err﹕ at libcore.io.Posix.bind(Native Method)
08-07 20:30:35.612 14669-14669/com.example.httpserver W/System.err﹕ at libcore.io.ForwardingOs.bind(ForwardingOs.java:56)
08-07 20:30:35.612 14669-14669/com.example.httpserver W/System.err﹕ at libcore.io.IoBridge.bind(IoBridge.java:97)
08-07 20:30:35.612 14669-14669/com.example.httpserver W/System.err﹕ ... 19 more
当我 select 来自网络浏览器的图像时,我只能看到:
uri: /sdcard/logo_etsiit.gif files {} parameters {} header
编辑:我用 WebServer class 解决了这个问题,现在我可以在我的网络浏览器中看到图像或 PDF selected
public class webserver extends NanoHTTPD {
FileInputStream fileInputStream;
public webserver(){
super(8080);
}
@Override
public Response serve(String uri, Method method, Map<String, String> header,Map<String, String> parameters, Map<String, String> files) {
String mediasend=getExtension(chosenFile);
FileInputStream fis = null;
try {
fis = new FileInputStream(Environment.getExternalStorageDirectory()
+ "/" + chosenFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return new NanoHTTPD.Response(etsiit.etsiitcast_def.NanoHTTPD.Response.Status.OK,mediasend,fis);
}
}
我也将这段代码添加到 onCreate:
//Get the ip of the device running NanoHTTPD server
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
ipdevice=String.format("http://%d.%d.%d.%d:8080",(ipAddress & 0xff),(ipAddress >> 8 & 0xff),(ipAddress >> 16 & 0xff),(ipAddress >> 24 & 0xff));
// start the webserver
mediaserver = new webserver();
try {
mediaserver.start();
} catch(IOException ioe) {
Log.d("Httpd", "The server could not start.");
}
我找到了问题的解决方案:我只需要将 MediaInfo mediaInfo = new MediaInfo.Builder( getString( R.string.video_url ) )
更改为 MediaInfo mediaInfo = new MediaInfo.Builder(ipdevice)
,其中 ipdevice
是我的 phone IP 地址(例如 http://192.168.1.40:8080).