连接 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();
}