首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >安卓: StreamProxy不使用Android5.x开发Nexus4/5

安卓: StreamProxy不使用Android5.x开发Nexus4/5
EN

Stack Overflow用户
提问于 2015-01-12 06:45:14
回答 1查看 312关注 0票数 2

下面是我在项目中使用的StreamProxy的一个来源

代码语言:javascript
复制
public class StreamProxy implements Runnable {
    private static final String LOG_TAG = "Stream proxy: %s";

    private int port = 0;
    private boolean isRunning = true;
    private ServerSocket socket;
    private Thread thread;

    public StreamProxy() {
        init();
        start();
    }

    public int getPort() {
        return port;
    }

    public String getProxyUrl(String uri, String tag) {
        return String.format("http://127.0.0.1:%d/%s", getPort(), uri);
    }

    private void init() {
        try {
            socket = new ServerSocket(port, 0, InetAddress.getByAddress(new byte[]{127, 0, 0, 1}));
            socket.setSoTimeout(5000);
            port = socket.getLocalPort();
            Timber.d(LOG_TAG, "port " + port + " obtained");
        } catch (IOException e) {
            Timber.e(e, "Error initializing server");
        }
    }

    private void start() {

        if (socket == null) {
            throw new IllegalStateException("Cannot start proxy; it has not been initialized.");
        }

        thread = new Thread(this);
        thread.start();
    }

    public void stop() {
        isRunning = false;

        if (thread == null) {
            throw new IllegalStateException("Cannot stop proxy; it has not been started.");
        }

        thread.interrupt();
        try {
            thread.join(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        Timber.d(LOG_TAG, "running");
        while (isRunning) {
            try {
                Socket client = socket.accept();
                if (client == null) {
                    continue;
                }
                Timber.d(LOG_TAG, "client connected");
                client.setKeepAlive(false);
                readRequest(client);

            } catch (SocketTimeoutException e) {
            } catch (IOException e) {
                Timber.e(e, "Error connecting to client");
            }
        }
        Timber.d(LOG_TAG, "Proxy interrupted. Shutting down.");
    }

    @Nullable
    private void readRequest(Socket client) throws IOException {
        InputStream is;
        String firstLine;
        try {
            is = client.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(is));
            firstLine = reader.readLine();
        } catch (IOException e) {
            Timber.e(LOG_TAG, "Error parsing request", e);
            return;
        }

        if (firstLine == null) {
            Timber.i(LOG_TAG, "Proxy client closed connection without a request.");
            return;
        }

        StringTokenizer st = new StringTokenizer(firstLine);
        st.nextToken();
        String uri = st.nextToken().substring(1);
        Timber.d(LOG_TAG, uri);
        processRequest(client, uri, "");
    }

    @Nullable
    private HttpURLConnection download(String path) throws IOException {
        URL url = new URL(path);
        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
        connection.connect();

        // expect HTTP 200 OK, so we don't mistakenly save error report
        // instead of the file
        if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
            throw new IOException("Server returned HTTP " + connection.getResponseCode()
                    + " " + connection.getResponseMessage());
        }
        return connection;
    }

    private void processRequest(Socket client, String url, String tag)
            throws IllegalStateException, IOException {

        Timber.d(LOG_TAG, "processing");
        HttpURLConnection realResponse = download(url);
        if (realResponse == null) {
            return;
        }

        InputStream data = realResponse.getInputStream();
        socketWriter.setClient(client);
        try {
            int readBytes;
            Timber.d(LOG_TAG, "writing data to client");
            // Start streaming content.
            byte[] buff = new byte[1024 * 8];
            while (isRunning && (readBytes = data.read(buff)) != -1) {
                client.getOutputStream().write(buff, 0, readBytes)
            }
            Timber.d(LOG_TAG, "end writing data");
        } catch (IOException e) {
            Timber.e(e, "Error data transfer to client");
        } finally {
            Timber.d(LOG_TAG, "finally block");
            if (data != null) {
                data.close();
            }
        }
    }
}

它在Android <5.0上运行得很好,但是在Android 5.0.+上,我在使用MediaExtractor(http://developer.android.com/reference/android/media/MediaExtractor.html)时出现了以下错误

代码语言:javascript
复制
NuCachedSource2﹕ source returned error -1, 10 retries left
NuCachedSource2﹕ source returned error -1, 9 retries left
...

使用Mediaplayer时没有错误消息,只有很少的静默重试。

也许对于Android 5,还有另一种通过缓存实现音频流的方法吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-29 14:18:32

流代理实际上运行良好。我从MediaExtractor获得的所有错误都是关于m4a容器的。对于大多数以m4a格式打包的文件,无法通过使用Android的组件通过流播放。除了三星,LG和其他一些具有这一功能的制造商的roms。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27896652

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档