Как транслировать и загружать мультимедиа из локального хранилища с помощью Android VideoView?

Мне нужно транслировать и загружать видеофайлы с сервера и показывать их в VideoView, что ж, благодаря Google, VV, естественно, не поддерживает мое требование, поэтому я сделал следующее:

1-создать HTTP-прокси с помощью NanoHTTPD и начать загрузку файла с сервера

2-запустите VideoView и установите uri на мой HTTP-прокси

3-внутренний сервер() в моем прокси. Я начал отвечать на VideoView так же, как настоящий сервер с соответствующими заголовками ответа (я имею в виду длину содержимого/диапазон содержимого с ответом 206)

но проблема начинается, когда VideoView, он правильно читает 300 КБ видеофайла, а после этого запрашивает от 619 КБ или что-то в этом роде. Я понятия не имею, почему VV хочет прыгнуть с 300 000 байт и внезапно перейти на 619 000 байт, и после 10 попыток он ответит мне ОШИБКОЙ -1004 внутри кода C++ VideoView, который я не мог найти. это.

Ниже приведено мое полное решение. любая помощь приветствуется, так как я ничего не знал о VideoView и его странном поведении!!!

Примечание: я намеренно исправил размер файла, в этом нет ничего плохого.

package com.example.videoBuffer2;

import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.MediaController;
import android.widget.VideoView;

import java.io.*;
import java.util.Map;

public class MyActivity extends Activity {
    /**
     * Called when the activity is first created.
     */
    Button btn;
    VideoView videoView;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        btn = (Button) findViewById(R.id.button);
        videoView = (VideoView) findViewById(R.id.videoView);
        MediaController mediaController = new
                MediaController(this);
        videoView.setMediaController(mediaController);
        final VideoStreamServer server = new VideoStreamServer(9090);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    server.start();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                videoView.setVideoURI(Uri.parse("http://127.0.0.1:9090/1.mp4"));
                videoView.requestFocus();

                videoView.start();
            }
        });
    }


    public class VideoStreamServer extends NanoHTTPD
    {

        public VideoStreamServer(int port) {
            super(port);
        }

        @Override
        public Response serve(String uri, Method method, Map<String, String> headers, Map<String, String> parms, Map<String, String> files) {

            //range=bytes=619814-
            long range;

            if (headers.containsKey("range"))
            {
                String contentRange = headers.get("range");
                range = Integer.parseInt(contentRange.substring(contentRange.indexOf("=") + 1, contentRange.indexOf("-")));
            }
            else
                range = 0;


            byte[] buffer;
            int constantLength = 256000;
            long bufLength=0;
            boolean isLastPart=false;
            try {

                RandomAccessFile ff =new RandomAccessFile(new File("/mnt/sdcard","1.mp4"),"rw" );
                long remainingChunk = ff.length() - range; //remaining
                if (remainingChunk < constantLength){
                    bufLength= remainingChunk; //means last part
                    isLastPart = true;
                }

                else
                    bufLength = constantLength;
                if (range !=0)
                    ff.seek(range);
                buffer= new byte[(int)bufLength];


                ff.read(buffer);


            } catch (FileNotFoundException e) {
                e.printStackTrace();
                buffer = new byte[0];
            } catch (IOException e) {
                e.printStackTrace();
                buffer = new byte[0];
            }
            Response response;
//            if (isLastPart)
//                response = new Response(Response.Status.OK,"video/mp4",new ByteArrayInputStream(buffer));
//            else
                response = new Response(Response.Status.PARTIAL_CONTENT,"video/mp4",new ByteArrayInputStream(buffer));

            response.addHeader("Content-Length","891064");
            response.addHeader("Content-Range",String.format("bytes %s-%s/%s", range,(range+bufLength),"891064"));
            Log.e("SERVER","Inside server sent " + String.format("bytes %s-%s/%s", range,(range+bufLength),"891064"));
            return response;

        }
    }
}

person Seyed Vahid Hashemi    schedule 06.10.2014    source источник


Ответы (1)


Наконец, я обнаружил, что моя проблема была не в коде, а в том, что носитель, который я использовал, не был стандартным в соответствии с документом Google.

Вы можете прочитать больше здесь: http://www.vahidhashemi.com/?p=120

person Seyed Vahid Hashemi    schedule 07.10.2014