Pergunta

I want an Android phone to control a video stream playback on a Samsung Smart TV. I can send a UPnP command to the TV with a URL to the video stream. Unfortunately the Samsung TV don't accept URLs that point outside the local network. To make a remote stream work I have to loop the traffic through my phone so it looks like it is a local URL to the Samsung TV.

I probably have to run a simple proxy type of a server on the phone. The phone always knows what the stream URL is so the proxy can be very simple one that always takes any incoming request and pipes it to the video stream on the external server.

I have tried running a socket connections and simply copying the input strem from the external server to the output stream of the socket server connection. While using this a web browser is able to download the file but all the metadata is lost and I also seem to get a broken pipe exception every time the file download finishes. Media players don't seem to understand the stream at all and there's no playback on VLC for example.

For the server I'm using a very simple piece of code like this:

    public class ServerThread implements Runnable {

    public void run() {
        try {
            if (SERVERIP != null) {

                serverSocket = new ServerSocket(SERVERPORT);

                while (true) {
                    // listen for incoming clients
                    Socket client = serverSocket.accept();
                    client.setSoTimeout(20000);
                    client.setKeepAlive(true);


                    OutputStream os = client.getOutputStream();

                    OutputStream out = new BufferedOutputStream(os);


                    InputStream is = openHttpConnection("<URL to the stream>");

                    copyStream(is, out);

And for the copy stream code:

    private static void copyStream(InputStream input, OutputStream output)
        throws IOException {
    int bytesRead;
    try {
        while ((bytesRead = input.read()) != -1) {
            output.write(bytesRead);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    output.flush();
    output.close();
    input.close();
}

Is there something I can do to simply forward all the metadata to the socket connection as well? Or am I doing something else wrong as well?

Are there any examples of serving video from Android phone to media players I could use to understand how to format the response stream correctly?

Thanks!!

Foi útil?

Solução

First: Dude! Didn't know you were here on SO! :-)

With the pleasantries out of the way...

I am guessing that your problem, at least in part, is that you are only copying the HTTP payload, not the entire HTTP response from the server. Hence, you are missing the 200 OK line and any requisite headers. This assumes that the unseen openHttpConnection() is using getInputStream() on an HttpUrlConnection, or the equivalent.

Options include:

  • Also serve getResponseCode(), getResponseMessage(), and headers reconstructed from getHeaderFields(), before serving that result stream.

  • Switch from HttpUrlConnection to just serving input from a raw socket that you use to manually make the HTTP request.

  • Find and use an existing HTTP reverse proxy engine or transparent proxy engine, such as one based off of a servlet, or perhaps one based on native code (after de-Tor-ing it, maybe)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top