Master255
@Master255

Media player, сохранение кэша на карту памяти — куда копать?

Мне необходимо сохранять файлы, которые играет медиа плеер в кэш в папку. С простыми звуковыми файлами нет проблем. Есть программа и класс, который это делает. Причём делает странным способом, но работает.

Большие проблемы с видео файлами.

Во-первых я хотел пойти по лёгкому пути и использовать мега вещь ExoPlayer от компании гудл. Но он не играет мой файл и по всей видимости много других
https://github.com/google/ExoPlayer/issues/19

Во-вторых я попробовал сделать свой стриминг в папку по тому же принципу, как и музыку. Вот мой код:
Этот класс стартует скачивание:
/**  
     * Download the url stream to a temporary location and then call the setDataSource  
     * for that local file
     */  
    public void downloadAudioIncrement(String mediaUrl) throws IOException {
    	URLConnection cn = new URL(mediaUrl).openConnection();   
    	path=mediaUrl;
        cn.connect();
        sizef=cn.getContentLength();
        InputStream stream = cn.getInputStream();
        if (stream == null) {
        	Log.e(getClass().getName(), "Unable to create InputStream for mediaUrl:" + mediaUrl);
        }
        
		downloadingMediaFile = new File(mContext.getCacheDir(),"downloadingMedia.dat");
		
		// Just in case a prior deletion failed because our code crashed or something, we also delete any previously 
		// downloaded file to ensure we start fresh.  If you use this code, always delete 
		// no longer used downloads else you'll quickly fill up your hard disk memory.  Of course, you can also 
		// store any previously downloaded file in a separate data cache for instant replay if you wanted as well.
		if (downloadingMediaFile.exists()) {
			downloadingMediaFile.delete();
		}

        FileOutputStream out = new FileOutputStream(downloadingMediaFile);   
        byte buf] = new byte[16384];
        int totalBytesRead = 0, incrementalBytesRead = 0;
        do {
        	int numread = stream.read(buf);   
            if (numread <= 0)   
                break;
            out.write(buf, 0, numread);
            totalBytesRead += numread;
            incrementalBytesRead += numread;
            totalKbRead = totalBytesRead/1000;
            
            testMediaBuffer();
           	//fireDataLoadUpdate();
        } while (validateNotInterrupted());   
       		stream.close();
        if (validateNotInterrupted()) {
	       //	fireDataFullyLoaded();
        }
    }


И постоянно запускает класс testMediaBuffer(). Который вот:
/**
     * Test whether we need to transfer buffered data to the MediaPlayer.
     * Interacting with MediaPlayer on non-main UI thread can causes crashes to so perform this using a Handler.
     */  
    private void  testMediaBuffer() {
	    Runnable updater = new Runnable() {
	        public void run() {
	            if (mMediaPlayer == null) {
	            	//  Only create the MediaPlayer once we have the minimum buffered data
	            	if ( totalKbRead >= INTIAL_KB_BUFFER) {
	            		try { 
	            			//mUri=Uri.parse(path);
	            			openVideo();
	            		} catch (Exception e) {
	            			Log.e(getClass().getName(), "Error copying buffered conent.", e);    			
	            		}
	            	}
	            } else if ((totalKbRead - pfile) >= 4000){ 
	            	//  NOTE:  The media player has stopped at the end so transfer any existing buffered data
	            	//  We test for < 1second of data because the media player can stop when there is still
	            	//  a few milliseconds of data left to play
	            	transferBufferToMediaPlayer();
	            }
	        }
	    };
	    handler.post(updater);
    }

И до этих пор всё нормально работает, но класс transferBufferToMediaPlayer(), который запускается тогда когда скаченный буфер превысит тот что был скачен до этого на 4мб, дропает звук и видео в момент подмены файла.

И как этот дроп обойти я не понимаю. По закомментированному видно, что здесь была война. Может, есть у кого предположения или опыт создания видео плеера со стримингом в папку? Вот код этого класса:
/**
     * Transfer buffered data to the MediaPlayer.
     * NOTE: Interacting with a MediaPlayer on a non-main UI thread can cause thread-lock and crashes so 
     * this method should always be called using a Handler.
     */  
    private void transferBufferToMediaPlayer() {
	    try { 
	    	// First determine if we need to restart the player after transferring data...e.g. perhaps the user pressed pause
	    	boolean wasPlaying = mMediaPlayer.isPlaying();
	    	
	    	
	    	// Copy the currently downloaded content to a new buffered File.  Store the old File for deleting later. 
	    	File oldBufferedFile = new File(mContext.getCacheDir(),"playingMedia" + counter + ".dat");
	    	File bufferedFile = new File(mContext.getCacheDir(),"playingMedia" + (counter++) + ".dat");

	    	//  This may be the last buffered File so ask that it be delete on exit.  If it's already deleted, then this won't mean anything.  If you want to 
	    	// keep and track fully downloaded files for later use, write caching code and please send me a copy.
	    	bufferedFile.deleteOnExit();   
	    	moveFile(downloadingMediaFile,bufferedFile);

	    	// Pause the current player now as we are about to create and start a new one.  So far (Android v1.5),
	    	// this always happens so quickly that the user never realized we've stopped the player and started a new one
	    	mMediaPlayer.pause();
	    	int curPosition = mMediaPlayer.getCurrentPosition();
	    	//mMediaPlayer.release();
	    	//mMediaPlayer=null;
	    	// Create a new MediaPlayer rather than try to re-prepare the prior one.
	    	
	    	FileInputStream fis = new FileInputStream(bufferedFile);
     		
	    	mMediaPlayer.reset();
            //mMediaPlayer = new MediaPlayer();

            /*if (mAudioSession != 0) {
                mMediaPlayer.setAudioSessionId(mAudioSession);
            } else {
                mAudioSession = mMediaPlayer.getAudioSessionId();
            }
            setListeners();*/
            pfile=bufferedFile.length()/1024;
            
            mMediaPlayer.setDataSource(fis.getFD());
            //mMediaPlayer.setSurface(new Surface (sf));
           // mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
            mMediaPlayer.prepare();
            // we don't set the target state here either, but preserve the
            // target state that was there before.
           // mCurrentState = STATE_PREPARING;
            //attachMediaController();
        	mMediaPlayer.seekTo(curPosition);
        	//mMediaPlayer.start(); 
    		//  Restart if at end of prior buffered content or mediaPlayer was previously playing.  
    		//	NOTE:  We test for < 1second of data because the media player can stop when there is still
        	//  a few milliseconds of data left to play
    		/*boolean atEndOfFile = (totalKbRead - pfile) >= 1000;
        	if (wasPlaying || atEndOfFile){
        	mMediaPlayer.start();
        	}*/

	    	// Lastly delete the previously playing buffered File as it's no longer needed.
	    	oldBufferedFile.delete();
	    	
	    }catch (Exception e) {
	    	Log.e(getClass().getName(), "Error -------------------------------------------------------", e);            		
		}
    }
  • Вопрос задан
  • 3229 просмотров
Решения вопроса 1
Master255
@Master255 Автор вопроса
в общем копаю в сторону vitamio. На нём написано много разных плееров.
Покопал и понял что месяц потерян зря.
Правильный ответ смотри тут Как сохранить кеш в MediaPlayer?
Или сразу тут https://github.com/master255/ImmortalPlayer
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@Alconnorry
Это один нормально.

ru.macblurayplayer.com/features.htm
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы