`
gryphone
  • 浏览: 433519 次
  • 性别: Icon_minigender_1
  • 来自: 苏州
社区版块
存档分类
最新评论

流媒体 播放 理论篇

阅读更多

流媒体播放

 

之所以为理论篇 因为该篇仅实现了播放功能 但还有一些其他待解决/完善功能 所以称之为理论篇

 

而且该篇以原理居多 故暂不释放源码

 

 

 

[原理]

写道
其实 原理很简单


1. 下载目标URI

2. 当下载了 96*10/8 Byte 开始播放之

3. 一边播放 一边下载

4. 当下载了 100 byte 暂停播放 重置播放目标 并继续播放

5. 下载完成后 重置播放目标 并继续播放

 

 

 

 

[代码 步骤]

 

1.  开辟Thread

 

public void startStreaming(final String mediaUri){
    	Runnable r = new Runnable(){
			@Override
			public void run() {
				// TODO Auto-generated method stub
				try {
					readStream(mediaUri);
				} catch (MalformedURLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
    		
    	};
    	
    	new Thread(r).start();
    	
    }

 

 

 

2. 创建目标URI 并下载之

 

public void readStream(String mediaUri) throws MalformedURLException, IOException{
    	URLConnection uc = new URL(mediaUri).openConnection();
    	uc.connect();
    	
    	InputStream is = uc.getInputStream();
    	if(is == null){
    	//error, InputStream is null
    	}
    	
    	dlMedia = new File(context.getCacheDir(),"downloadingMedia.dat");
    	if(dlMedia.exists()){
    		dlMedia.delete();
    	}
    	
    	FileOutputStream fo = new FileOutputStream(dlMedia);
    	
    	byte buf[] = new byte[16384];
    	loadByte = 0;
    	
    	do {
    		int numread = is.read(buf); 
    		
    		loadByte += numread;
    		
    		if(numread <= 0){//end of stream, so exist
        		break;
        	}
    		
    		fo.write(buf, 0, numread);
    		
    		testMediaBuffer();
    	}
    	while(true);
    	is.close();
    	
    	//buffer all stream to MediaPlayer if end of stream
    	transferBufferToMediaPlayer();
    

 

 

 

3. 根据此刻下载的byte 判断是:开始播放 还是 缓冲下载数据

 

public void testMediaBuffer(){
    	Runnable update = new Runnable(){
			@Override
			public void run() {
				// TODO Auto-generated method stub
				//initial MediaPlayer if null
				if(mp == null){
					if(loadByte >= INTIAL_KB_BUFFER){
						loadByte = 0;
						
						startMediaPlayer();
					}
				}//load buffer while 1000
				else if(loadByte > BUFFER_KEY_BYTE) {
					
					loadByte = 0;
					transferBufferToMediaPlayer();
				}
			}
    		
    	};
    	
    	handler.post(update);
    }

 

 

 

4. 开始播放 并跟踪播放进度

 

public void startPlayProgressUpdater() {
    	//float progress = mp.getCurrentPosition();
    	
    	if (mp.isPlaying()) {
    		Runnable notification = new Runnable() {
    	        public void run() {
    	        	startPlayProgressUpdater();
    			}
    	    };
    	    handler.postDelayed(notification,100);
    	}
    }
    
    public void startMediaPlayer() {
        try {   
        	File bufferedFile = new File(context.getCacheDir(),"playingMedia" + (counter++) + ".dat");
        	
        	// We double buffer the data to avoid potential read/write errors that could happen if the 
        	// download thread attempted to write at the same time the MediaPlayer was trying to read.
        	// For example, we can't guarantee that the MediaPlayer won't open a file for playing and leave it locked while 
        	// the media is playing.  This would permanently deadlock the file download.  To avoid such a deadloack, 
        	// we move the currently loaded data to a temporary buffer file that we start playing while the remaining 
        	// data downloads.  
        	moveFile(dlMedia,bufferedFile);

        	mp = createMediaPlayer(bufferedFile);
        	
    		// We have pre-loaded enough content and started the MediaPlayer so update the buttons & progress meters.
        	mp.start();
        	
        	startPlayProgressUpdater();
        } catch (IOException e) {
        	//Log.e(getClass().getName(), "Error initializing the MediaPlayer.", e);
        	return;
        }   
    }

 

 

 

5. 缓冲下载数据

 

private void transferBufferToMediaPlayer() {
        try {
        	//remember current position 
        	int curPosition = mp.getCurrentPosition();
        	
        	// Copy the currently downloaded content to a new buffered File.  Store the old File for deleting later. 
        	File bufferedFile = new File(context.getCacheDir(),"playingMedia" + (counter++) + ".dat");

        	moveFile(dlMedia,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
        	mp.pause();
        	
        	// Create a new MediaPlayer rather than try to re-prepare the prior one.
        	mp = createMediaPlayer(bufferedFile);
    		mp.seekTo(curPosition);

    		mp.start();
    		
        	// Lastly delete the previously playing buffered File as it's no longer needed.
        	bufferedFile.delete();
        	
        }catch (Exception e) {
        //error, to print
    	}
    }

 

 

6. 文件移动

 

private void moveFile(File oldLocation, File	newLocation)
    throws IOException {

    	if ( oldLocation.exists( )) {
    		BufferedInputStream  reader = new BufferedInputStream( new FileInputStream(oldLocation) );
    		BufferedOutputStream  writer = new BufferedOutputStream( new FileOutputStream(newLocation, false));
            try {
    	        byte[]  buff = new byte[8192];
    	        int numChars;
    	        while ( (numChars = reader.read(  buff, 0, buff.length ) ) != -1) {
    	        	writer.write( buff, 0, numChars );
      		    }
            } catch( IOException ex ) {
    			throw new IOException("IOException when transferring " + oldLocation.getPath() + " to " + newLocation.getPath());
            } finally {
                try {
                    if ( reader != null ){                    	
                    	writer.close();
                        reader.close();
                    }
                } catch( IOException ex ){
    			    //Log.e(getClass().getName(),"Error closing files when transferring " + oldLocation.getPath() + " to " + newLocation.getPath() ); 
    			}
            }
        } else {
    		throw new IOException("Old location does not exist when transferring " + oldLocation.getPath() + " to " + newLocation.getPath() );
        }
    }

 

 

 

7. 播放指定目标

 

private MediaPlayer createMediaPlayer(File mediaFile)
    throws IOException {
    	MediaPlayer mPlayer = new MediaPlayer();

    	//  It appears that for security/permission reasons, it is better to pass a FileDescriptor rather than a direct path to the File.
    	//  Also I have seen errors such as "PVMFErrNotSupported" and "Prepare failed.: status=0x1" if a file path String is passed to
    	//  setDataSource().  So unless otherwise noted, we use a FileDescriptor here.
    	FileInputStream fis = new FileInputStream(mediaFile);
    	mPlayer.setDataSource(fis.getFD());
    	mPlayer.prepare();
    	return mPlayer;
    }
 

 

8. Toast 信息提示:

 

public void popMsg(String msg){
    	Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
    }

 

 

9. done, plx test it, post feedback, thanks

 

分享到:
评论
2 楼 gryphone 2010-05-28  
bingtian 写道
你好,这个如果已经播放缓冲的,音乐停止了,等缓冲开始多了,音乐还会继续播放吗?

是的啊 但是从效果看不是太好 我现在也在寻找更smooth的方法
1 楼 bingtian 2010-05-28  
你好,这个如果已经播放缓冲的,音乐停止了,等缓冲开始多了,音乐还会继续播放吗?

相关推荐

    关于播放流媒体文件续

    标题中的“关于播放流媒体文件续”提示我们这篇博文可能是对之前讨论的流媒体播放技术的延续或深入探讨。在IT行业中,流媒体文件是指在传输过程中被连续接收和播放的多媒体内容,如在线视频、音频等。这些文件通常...

    P2P 流媒体技术论文

    总的来说,"基于P2P的流媒体技术"这篇论文应该涵盖了P2P流媒体的核心原理、实现技术和潜在问题,对于理解这个领域的理论和实践都有重要的参考价值。通过深入阅读和分析,我们可以更全面地了解如何利用P2P技术来优化...

    p2p与流媒体技术的结合

    总的来说,这四篇论文全面地探讨了P2P技术与流媒体的结合,从理论到实践,从模型设计到实际应用,为理解P2P在流媒体领域的潜力提供了深入的洞察。通过深入阅读这些论文,读者可以深入了解P2P流媒体技术的工作原理,...

    基于p2p的流媒体点播源码

    通过深入理解和学习这个基于P2P的流媒体点播源码,开发者不仅可以掌握P2P网络的基本原理,还能了解到如何将这些理论应用于实际的流媒体点播系统中。这对于理解网络通信、流媒体处理以及跨平台开发具有很高的学习价值...

    论文研究-流媒体在WCDMA网中的应用研究.pdf

    综上所述,流媒体在WCDMA网中的应用研究涉及了基础理论、体系结构设计、关键技术和应用案例等多方面内容。随着移动通信技术的不断发展和网络带宽的提升,流媒体技术将在移动互联网领域发挥越来越重要的作用。本篇...

    P2P 分层流媒体中数据分配算法.pdf

    综上所述,这篇文章详细探讨了分层P2P流媒体中的数据分配问题,并给出了有效的算法解决方案,这些内容对于理解P2P流媒体技术以及设计高效的数据分配算法具有较高的理论价值和实践意义。通过阅读这篇文献,IT专业人员...

    基于智能手机的流媒体客户端研究与实现论文.doc

    总的来说,这篇论文深入研究了基于智能手机的流媒体客户端的开发,涵盖了从技术标准、系统平台到具体实现的各个环节。对于想要了解和开发移动流媒体应用的工程师和研究人员来说,具有很高的参考价值。它不仅提供了...

    流媒体服务器安装与配置分享.pdf

    总的来说,这篇文档提供了一个完整的流媒体服务器构建教程,涵盖了从基础的DNS设置到专业流媒体服务器的安装和调试。通过这样的实践,读者不仅能学习到理论知识,还能积累实际操作经验,为日后搭建和管理流媒体系统...

    毕业设计基于测量在线视频流媒体质量因素分析.docx

    本篇毕业设计旨在通过数据测量和分析,揭示影响在线视频流媒体质量的关键因素,为优化服务质量提供理论依据。 首先,研究内容主要包括对视频流媒体业务的基本特征的了解。这涵盖了流媒体技术的工作原理,如流式传输...

    基于网络处理器的流媒体应用架构模型(VPL).pdf

    《基于网络处理器的流媒体应用架构模型(VPL)》这篇文章主要探讨了在网络处理器上实现流媒体应用的...这篇研究为网络处理器上的流媒体应用提供了重要的理论基础和实践指导,对于理解和优化此类应用的性能具有重要意义。

    基于FFMpeg的稳定应用层组播流媒体直播系统研究1

    【标题】:“基于FFmpeg的稳定应用层组...总的来说,这篇论文深入研究了基于FFmpeg的稳定应用层组播流媒体直播系统,旨在解决组播技术在实际应用中遇到的稳定性问题,为构建高效、可靠的流媒体服务提供理论和技术支持。

    Ijkplayer rtsp http 播放

    在Android开发中,实现视频流媒体播放是一个常见的需求,尤其涉及到RTSP(Real Time Streaming Protocol)和HTTP协议时。IJKplayer是一个广受欢迎的开源媒体播放器库,它为开发者提供了强大的功能,支持多种视频格式...

    Android系统中RTMP流媒体直播的设计与实现.pdf

    《Android系统中RTMP流媒体直播的设计与实现》这篇文献主要探讨了在Android平台上利用RTMP协议进行高清音视频实时传输的技术方案,特别是在无线通信环境恶劣的地区如何保证远程视频监控的质量。RTMP(Real-Time ...

    长尾理论完结篇

    2. **在线视频流媒体**:Netflix、Amazon Prime Video等平台通过提供广泛的内容选择,包括经典电影、独立电影、国际剧集等,满足了不同观众群体的多样化需求,而非仅仅依赖于几部超级大片。 3. **电子商务**:...

Global site tag (gtag.js) - Google Analytics