在android中怎么读取视频文件呢?读取一个.yuv类型视频文件,并把该文件保存为byte[]类型的;
我用的方法出现 Out of Memoryerror错误;
代码如下:
public static byte[] getByetsFromFile(File file) {
byte[]buffer = null;
ByteArrayOutputStream bos =null;
try{ 
FileInputStream fis = new FileInputStream(file);
bos=new ByteArrayOutputStream();
buffer = new byte[1024];
int length = 0;
while((length = fis.read(buffer))!= -1){
bos.write(buffer, 0, length);

fis.close();
bos.close(); 
return bos.toByteArray();//字节流转换为一个 byte数组然后采用byte[] yuv = getByetsFromFile(new File("sdcard/foreman.yuv"));  
请问大家该如何修改呢?

解决方案 »

  1.   

    我的这个视频文件的大小为10M,算是比较小的视频了,随便一个视频文件都比较大,是不是我的这个读取的方法不对呢?该如何修改呢?想的是在java中yuv视频转换成rgb565,然后直接用Bitmap.createBitmap(); canvas.drawBitmap()将该视频显示出来
      

  2.   

    切成一小块一小块的来转,比如yuyv格式的,按顺序每次只提取100帧的数据来处理
      

  3.   

    提取帧的方法可以参考:
    http://www.fourcc.org/yuv.php
      

  4.   

    这个YUV的帧的处理我在后面写好了(是YUV转RGB565的),现在是内存溢出的问题啊,网上说不要用ByteArrayOutputStream读到内存中去
      

  5.   

    你的while循环读写的太快了吧,加个线程让他一点一点来
      

  6.   

    应该不是while循环的读的快的问题吧,是不是ByteArrayOutputStream读到内存这个方式不对呢
      

  7.   

    就是buffer开的太大了,分批来不要一次取完
    以你这算法,就算10M能取,那100M、1G、10G呢,再好的配置也会有撑爆的一天
      

  8.   

    ByteArrayOutputStream 这个的问题  你看下api,你从buffer 读出来,又写的buffer中了  造成了死循环
      

  9.   

    现在换成这个样的:
        public static byte[] getByetsFromFile(File file){
         FileInputStream is = null;
         // 获取文件大小
         long length = file.length();
          // 创建一个数据来保存文件数据
         byte[] fileData = new byte[(int)length];
        
         try {
         is = new FileInputStream(file);
         } catch (FileNotFoundException e) {
                e.printStackTrace();
         }
         int bytesRead=0;
         // 读取数据到byte数组中
         while(bytesRead != fileData.length) {
            try {
            bytesRead += is.read(fileData, bytesRead, fileData.length - bytesRead);
    if(is != null)
    is.close();
    } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }    
         }
         return fileData;
        }
    没有Out of Memoryerror错误了,不过运行出来的是
      

  10.   

     假设test.yuv保存的是320*240的yuyv格式数据,现在要将其转换为RGB565并显示到界面:public void PlayYUVYFile()
        {
           int readCount=0; //已经从YUYV读取的次数
           int frameCountPerTime=2;//每次读取的帧数,考虑YUYV的数据排列方式,每次读取2或2的倍数帧比较好处理
           
           byte[] buffYUYV = new byte[1024];
           
           File file = new File("/mnt/sdcard/test.YUV");
           int length=0;
           do
           {
            length= getByetsFromYUYVFile(file,buffYUYV,readCount,frameCountPerTime);//读取了2帧的YUV数据
            
            byte[] buffRGB565= ConvertYUYVToRGB565(buffYUYV,frameCountPerTime);//转换后得到2帧的RGB565数据
            
            for(int i=0;i<frameCountPerTime;i++)
            {
           // 将每帧的RGB565数据绘制到界面
            }
            
            readCount++;
           }while(length==frameCountPerTime*2);
           
        }
        
        private byte[] ConvertYUYVToRGB565(byte[] buffYUYV,int frameCountPerTime)
        {
         byte[] buffRGB565=null;
          // 将YUYV的数据转换为GRB565
          // 返回GRB565数据
         return buffRGB565;
        }
        
        private int getByetsFromYUYVFile(File file,byte[] buffer,int readCount,int frameCountPerTime) {
        
         int length = 0;
         FileInputStream fis =null;
        
         try
         {
           fis = new FileInputStream(file);
           length=fis.read(buffer, readCount*320*240*2*frameCountPerTime, 2*frameCountPerTime);
           fis.close();
         }
         catch(Exception ex)
         {
         //to do
         }
        
         return length;
        }
      

  11.   

    yuyv是最简单的排列格式,是比较好处理,
    像NV21、YV12等稍微麻烦点,需要在方法getByetsFromYUYVFile中通过一番计算才能找到要读取的帧数据
      

  12.   

    其实这部分全丢到C里头做,是不会发生OOM的。坑爹的ANDROID,坑爹的虚拟机
      

  13.   

    需要在方法getByetsFromYUYVFile中通过一番计算才能找到要读取的帧数据,这点怎么计算呢?是在fis.read的第二个参数上面计算吗 真心不懂啊
      fis = new FileInputStream(file);
      length=fis.read(buffer, readCount*320*240*2*frameCountPerTime, 2*frameCountPerTime);
      

  14.   

    是的,读取要弄清楚当前正在读取的是第几帧的数据,该帧的V、U、V分别存在什么地方。参考http://www.fourcc.org/yuv.php,弄清各种格式的排列方式之后其实也难不到哪了
      

  15.   

    yuv数据实在是太大了,只是几秒的数据都哟数十M了。
    在JNI中进行解码效率相对高些吧。
      

  16.   

    yuv的数据应该不用解码吧,将其转换为RGB565直接VideoBit.copyPixelsFromBuffer(bufferRGB);canvas.drawBitmap(VideoBit, 0, 0, null);就可以了