简体   繁体   English

如何使用Android的VideoView从本地存储流式传输和下载媒体?

[英]How to stream and download a media from local storage using Android's VideoView?

I have to stream and download video files from a server and show it in VideoView, well thanks to google, VV doesn't support my requirement naturally so this is what I have done: 我必须从服务器流式传输和下载视频文件,并在VideoView中显示它,感谢谷歌,VV自然不支持我的要求,所以这就是我所做的:

1-create a HTTP proxy using NanoHTTPD and start downloading a file from server 1-使用NanoHTTPD创建HTTP代理并开始从服务器下载文件

2-start VideoView and set uri to my HTTP proxy 2启动VideoView并将uri设置为我的HTTP代理

3-inside server() in my proxy I started to response to VideoView same as a real server with appropriate response headers ( I mean content-length/content-range with 206 response) 我的代理服务器内部有3个内部服务器(),我开始对VideoView进行响应,就像使用具有适当响应头的真实服务器一样(我的意思是content-length / content-range带有206响应)

but the problem starts when VideoView, it reads like 300kb of video file properly and after that it requests from 619kb or something. 但是问题开始于VideoView,它可以正常读取300kb的视频文件,然后再从619kb或其他内容进行请求。 I don't have any clue why would VV wants to hop from 300,000bytes and suddenly jump to 619,000bytes , and after 10 attempts it will respond me with ERROR -1004 inside c++ code of VideoView which I couldn't find any clue what is that. 我没有任何线索,为什么VV要从300,000bytes跳到突然跳到619,000bytes,经过10次尝试,它会在VideoView的c ++代码内以错误-1004响应我,我找不到任何线索是什么那。

following is my complete solution. 以下是我的完整解决方案。 any help is appreciated as I became clueless about VideoView and it's bizarre behavior!!! 感谢任何帮助,因为我对VideoView一无所知,这是一种奇怪的行为!!!

Note : I have fixed the size of file deliberately, nothing wrong with it. 注意:我故意修复了文件的大小,没有任何问题。

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;

        }
    }
}

Finally I found out my problem the problem wasn't with the code but the media I have used wasn't standard according to google's doc. 最终,我发现了问题所在,并不是代码,但根据Google的文档,我使用的媒体不是标准的。

You can read more here : http://www.vahidhashemi.com/?p=120 您可以在此处了解更多信息: http : //www.vahidhashemi.com/?p=120

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 MediaStore 将媒体文件从 FirebaseStorage 下载到本地存储? - How to download a media file from FirebaseStorage to local storage using MediaStore? 使用 VideoView 从内部存储 android 播放视频文件 - Play video file from internal storage android using VideoView 如何从内部存储在Videoview或WebView中的Android中播放视频 - How to Play Video in Android in Videoview or WebView from Internal Storage 如何从Android的VideoView中播放的RTSP流中消除延迟 - How to remove lag from RTSP stream playing in a VideoView on Android Android Media Player:从文件下载到文件和流 - Android Media Player: Download to File and Stream From File 如何在 Android 中使用 .setPhotoUri 从本地存储添加图片以更新 Firebase 用户的照片配置文件? - How to add a picture from local storage to update Firebase user's photo profile using .setPhotoUri in Android? 如何在内部存储中下载和保存媒体文件 android java - how to download and save media files in internal storage android java Android MediaPlayer无法播放本地存储中的媒体文件 - Android MediaPlayer unable to play media file from local storage 如何从 Android 本地存储中获取媒体文件(图像、视频、音频)? - How to fetch media files (Images,videos,audio) from Android local storage? 如何使用 Android 中的 WorkManager 从 Firebase 存储中下载文件 - How to download files from Firebase Storage using WorkManager in Android
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM