基于Android平台的移动流媒体播放器的开发

主页界面如下

第一部分 课题相关介绍

与普通播放器相比,流媒体播放器最主要的不同点在于其能够实现实时的视频播放,用户可以实现边加载边播放,不需要一次全下载完视频。

流媒体技术

流媒体技术简单来说就是将完整视频先行数据压缩,再分段发送数据,实时传播时由于容量较小,传输就非常快速,可以基本实现实时浏览的一种技术。

简单概括为:采用了"流式传输"技术,文件象水流那样流动

流媒体主要分为两种:

1.顺序流式传输 HTTP渐进下载

在下载文件的同时用户可观看在线媒体,由于标准的HTTP服务器可发送这种形式的文件,它经常被称作HTTP流式传输。顺序流式文件易于管理,但不支持现场直播,严格地说是一种点播技术。

HTTP网络视频的实现

2.实时流式传输 基于RTSP/RTP的实时流媒体协议

需要专用的流媒体服务器与传输协议。实时流式传输总是实时传送,特别适合现场事件,可用于直播等的实现。

平台选择

Android平台的优点

目前移动手机市场

第二部分 系统分析及相应实现

首先明确系统功能以及性能需求,之后对系统进行总体设计,将系统分为视频采集模块,视频播放模块以及视频裁剪模块。

需求分析

1.基本需求:视频播放

(1)本地视频播放

(2)视频点播

(3)视频直播

2.界面美观,操作简便

(1)实现动态切换全屏/原屏、横屏/竖屏的自由切换

(2)监控视频播放器窗口的滑动,实现亮度加减,音量加减,快进和快退功能

(3)本地视频资源管理

采集子系统

Android6.0发布以来,在权限上做出了很大的变动,不再是之前的只要在manifest设置就可以任意获取权限,不会再强迫用户因拒绝不该拥有的权限而导致的无法安装的事情,也不会再不征求用户授权的情况下,就可以任意的访问用户隐私,而且即使在授权之后也可以及时的更改权限。

//对于6.0以后的机器动态权限申请

public void Accessibility() {

if (Build.VERSION.SDK_INT >= 23) {

int checkCallPhonePermission = ContextCompat.checkSelfPermission(CameraActivity.this, Manifest.permission.CAMERA);

int checkCallPhonePermission2 = ContextCompat.checkSelfPermission(CameraActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE);

int checkCallPhonePermission3 = ContextCompat.checkSelfPermission(CameraActivity.this, Manifest.permission.RECORD_AUDIO);

if (checkCallPhonePermission != PackageManager.PERMISSION_GRANTED &&checkCallPhonePermission2 != PackageManager.PERMISSION_GRANTED && checkCallPhonePermission3 != PackageManager.PERMISSION_GRANTED) {

ActivityCompat.requestPermissions(CameraActivity.this, new String[]{Manifest.permission.CAMERA,Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO}, REQUEST_CODE_ASK_CALL_PHONE);

return;

} else {

initViews();

}

} else {

initViews();

}

}

1.初始化设置

采集过程主要是设置 MediaRecorder 类的一些参数和采集数据的缓存,使用了 Android 系统自带的MediaRecorder 类进行采集。

定义一个录制视频的 MediaRecorder 子类 mRecorder,指定录制的采集方式、文件的输出方式以及编码格式,录音方式采用AMR_NB 编码,视频采用H.264编码。

mRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);

mRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);

mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);

mRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);

2.设置输出文件的本地路径

String path = Environment.getExternalStorageDirectory().getPath();

if (path != null) {

File dir = new File(path + "/360");

if (!dir.exists()) {

dir.mkdir();

}

path = dir + "/" + System.currentTimeMillis() + ".mp4";

mRecorder.setOutputFile(path);

3.开始录制

调用 prepare 方法,准备采集,prepare 方法将使用 Android 系统自带的本地 LocalSocket 和 LocalServerSocket 进行数据的缓存,然后使用start方法开始录制

mRecorder.prepare();

mRecorder.start(); //开始录制

4.停止录制,释放MediaRecorder以及相机资源

播放子系统

1.本地视频播放

使用surfaceview+MediaPlayer自定义播放器 播放本地视频

surfaceView创建完成再开始播放视频

surfaceCreated()

surfaceChanged()

surfaceDestroyed()

mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener()

{

@Override

public void onPrepared(MediaPlayer mp)

{

// 开始播放视频

mediaPlayer.start();

// 设置总时长

tvDuration.setText(mp.getDuration() / 1000 + "");

tvCurrentT.setText(mp.getCurrentPosition() / 1000 + "");

progressBar.setMax(mp.getDuration());

updateView();

}

});

2.视频点播(被用户任意观看,每次都可从头播放)

surfaceDestroyed()

mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener()

{

@Override

public void onPrepared(MediaPlayer mp)

{

// 开始播放视频

mediaPlayer.start();

// 设置总时长

tvDuration.setText(mp.getDuration() / 1000 + "");

tvCurrentT.setText(mp.getCurrentPosition() / 1000 + "");

progressBar.setMax(mp.getDuration());

updateView();

}

});

播放控件使用Android自带的 VideoView 控件,采用MediaController媒体控制器实现播放

(1)视频缓冲Gif加载

videoView1.setOnInfoListener(new MediaPlayer.OnInfoListener() {

@Override

public boolean onInfo(MediaPlayer mp, int what, int extra) {

if(what == MediaPlayer.MEDIA_INFO_BUFFERING_START){

//Toast.makeText(MainActivity.this, "正在缓冲", Toast.LENGTH_LONG).show();

loadingGif.setVisibility(View.VISIBLE);

Log.w(TAG,"正在缓冲");

}else if(what == MediaPlayer.MEDIA_INFO_BUFFERING_END){

//此接口每次回调完START就回调END,若不加上判断就会出现缓冲图标一闪一闪的卡顿现象

if(mp.isPlaying()){

//Toast.makeText(MainActivity.this, "缓冲结束", Toast.LENGTH_LONG).show();

loadingGif.setVisibility(View.GONE);

Log.w(TAG,"缓冲结束");

videoView1.setVisibility(View.VISIBLE);

}

}

return true;

}

});

(2)网络视频地址跳转播放

测试地址:

rtsp://184.72.239.149/vod/mp4://BigBuckBunny_175k.mov

http://mirror.aarnet.edu.au/pub/TED-talks/911Mothers_2010W-480p.mp4

//输入网络视频地址

mediaUri=Uri.parse(((EditText)findViewById(R.id.id_internetUri)).getText().toString());

videoView1.setMediaController(new MediaController(InternetActivity.this));

videoView1.setVideoURI(mediaUri);

videoView1.requestFocus(); // 获取焦点

videoView1.start();

3.视频直播: 正在发生的画面

(1) ijkplayer简化

android studio集成ijkplayer,将其作为moudle导入我们需要使用播放器的工程project中,由于要实现简单的网络直播播放功能,这里生成fastvideoplay来将ijkplay的功能进行简化

IjkVideoView 这个类是使用ijkplayer播放的View,这里为了操作方便,直接使用IjkVideoView作为直播的播放器

```

```

初始化视图

```

try {

IjkMediaPlayer.loadLibrariesOnce(null);

IjkMediaPlayer.native_profileBegin("libijkplayer.so");

playerSupport = true;

} catch (Throwable e) {

Log.e("GiraffePlayer", "loadLibraries error", e);

}

```

(2) 网络直播视频处理

surfaceDestroyed()

videoPlayer = findViewById(R.id.fastvideo_player);

play = findViewById(R.id.play);

videoPlayer.setLive(true);

videoPlayer.setScaleType(FastVideoPlayer.SCALETYPE_FITXY);

videoPlayer.setTitle("CCTV5直播");//设置标题

videoPlayer.setUrl("http://ivi.bupt.edu.cn/hls/cctv5phd.m3u8");

4.播放功能的优化

(1)监控视频播放窗口的滑动,实现亮度加减,音量加减,快进和快退功能

以音量加减举例:

```

private float downX, downY;//手指刚开始滑动时记录点 X轴 Y轴

switch (event.getAction())

{

case MotionEvent.ACTION_DOWN://手指按下

downX = event.getX();//按下时记录相关值

downY = event.getY();

break;

case MotionEvent.ACTION_MOVE://手指滑动

// TODO 音量

float distanceX = event.getX() - downX;//滑动距离

float distanceY = event.getY() - downY;

//减小音量条件:右半边屏幕,滑动距离一定且向下滑动

if (downX > 0.75*screenWidth

&& Math.abs(distanceX) < 50

&& distanceY > FACTOR)

{

// TODO 减小音量

setVolume(false);

}

else if (downX > 0.75*screenWidth

&& Math.abs(distanceX) < 50

&& distanceY < -FACTOR)

{

// TODO 增加音量

setVolume(true);

}

音量管理函数

private void setVolume(boolean flag)

{

// 获取音量管理器

AudioManager manager = (AudioManager) getSystemService(AUDIO_SERVICE);

// 获取当前音量

int curretnV = manager.getStreamVolume(AudioManager.STREAM_MUSIC);

if (flag)

{

curretnV++;

}

else

{

curretnV--;

}

manager.setStreamVolume(AudioManager.STREAM_MUSIC, curretnV,

AudioManager.FLAG_SHOW_UI);

tvSound.setVisibility(View.VISIBLE);

tvSound.setText("音量:" + curretnV);

handler.postDelayed(new Runnable()

{

@Override

public void run()

{

tvSound.setVisibility(View.GONE);

}

}, 1000);

}

(2)动态切换全屏/原屏、横屏/竖屏的自由切换。

利用全屏/原屏切换函数,即可自由切换全/原屏

public void fullScreenChange() {

SharedPreferences mPreferences = PreferenceManager

.getDefaultSharedPreferences(this);

boolean fullScreen = mPreferences.getBoolean("fullScreen", false);

WindowManager.LayoutParams attrs = getWindow().getAttributes();

System.out.println("fullScreen的值:" + fullScreen);

if (fullScreen) {

attrs.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);

getWindow().setAttributes(attrs);

// 取消全屏设置

getWindow().clearFlags(

WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

mPreferences.edit().putBoolean("fullScreen", false).commit();

} else {

attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;

getWindow().setAttributes(attrs);

getWindow().addFlags(

WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

mPreferences.edit().putBoolean("fullScreen", true).commit();

}

}

对于横竖屏的切换:设置权限,在AndroidManifest.xml中对Activity属性进行设置android:configChanges属性

android:configChanges="keyboardHidden|orientation|screenSize"

(3)本地视频资源管理

在Activity Action中有一个“ACTION_ GET_ CONTENT”字符串常量。 此常量允许用户选择特定类型的数据并返回数据的URI。 我们利用这个常量,然后将类型设置为 video / * 以获取Android手机中的所有视频。

Intent intent = new Intent();

intent.setType("video/*");

intent.setAction(Intent.ACTION_GET_CONTENT);

startActivityForResult(intent, 1);

之后从媒体管理器返回,利用mediaUri = data.getData()获取本地视频文件路径,然后在视频播放端使用VideoView进行播放。

#### 裁剪子系统

代码详见:https://github.com/iknow4/Android-Video-Trimmer

(1)FFmpeg移植到Android平台

在本项目开发中采用Java封装FFmpeg命令行,而没有采用一般的Java+C语言来进行开发,使之在Android项目中轻松执行FFmpeg和FFprobe命令。采用开源项目Bravobit FFmpeg-Android加载FFmpeg库:

(2)裁剪功能的实现

android 流播放器开发,GitHub - youcoding98/FastVideo: 基于Android平台的移动流媒体播放器的开发...相关推荐

  1. 《音视频开发进阶指南:基于Android与iOS平台的实践》源码下载地址

    年前买了这本书,想看下随书源码,一开始从CSDN下载频道下载电子书+源码,但那个源码不是这边书的. 从网上找了一段时间,终于找到了(其实在书的前言/勘误和支持中有给出),作者展晓凯的相关网站如下: 作 ...

  2. 基于android的视频采集系统的设计与实现,基于Android的视频通话系统的设计与实现.docx...

    基于Android的视频通话系统的设计与实现 基于Android的视频通话系统的设计与实现摘 要近年来,智能手机操作系统发展迅速,尤其是Android系统的迅猛发展已经将全球智能手机市场引领到了非常火 ...

  3. python3.7魔塔游戏_基于Funcode平台的“火锅版魔塔”游戏开发与设计

    2019 年第 2 期 信息与电脑 China Computer & Communication 软件开发与应用 基于 Funcode 平台的"火锅版魔塔"游戏开发与设计 ...

  4. 基于android平台多媒体播放器的设计与实现,基于Android的多媒体音乐播放器设计论文...

    中图分类号:TP317 文献标识码:A 文章编号:1009-3044(2016)03-0240-02 随着计算机网络与手机的迅速发展,各种音乐资源成为人们生活中必不可少的一部分,音乐播放软件成了手机必 ...

  5. php mysql 开发微博_php+mysql基于Android的手机微博应用开发

    摘要:本系统采用Eclipse作为开发工具,数据库基于MySQL,服务器的编写使用的是PHP语言,开发了基于Android平台开的C/S模式的手机微博系统.系统从符合操作简便.界面友好.使用灵活.实用 ...

  6. android租车管理系统,毕业设计(论文)-基于Android的学校租车管理系统的设计与开发.doc...

    盐城师范学院毕业设计 盐 城 师 范 学 院 毕业设计 基于Android的学校租车管理系统 的设计与开发 学生姓名 学 院 信息工程学院 专 业 数字媒体技术 班 级 12(1) 学 号 指导教师 ...

  7. Android开发英语听力软件,基于Android平台的大学英语听力学习系统的设计与实现...

    摘要: 随着信息技术的飞速发展,移动设备给学习提供了一种全新的学习模式,使学者能够在任何时间.任何地点获得自己想要的知识,实现自主学习.本文对基于Android平台的大学英语听力学习系统展开研究,旨在 ...

  8. (转)KVAudioStreamer - 基于AudioToolBox的开源音频流媒体播放器

    原贴的地址:https://www.jianshu.com/p/7b40f0e8b6bb 在iOS上,播放音频一般使用AVAudioPlayer进行音频播放,但是AVAudioPlayer并不支持流媒 ...

  9. android文件管理实现所应用到的技术,基于Android的文件管理系统的设计与实现

    摘要: 现如今,移动信息化得到了不断的发展.在手机,掌上电脑等智能终端进行的随时随地的移动化办公方式,越来越得到人们的欢迎.Android是一款应用广泛的操作系统,在大量开发者的努力下,基于Andro ...

最新文章

  1. ajax为什么会全局刷新,为什么发送ajax请求页面也会刷新呢?
  2. Java集合面试问题
  3. 学习笔记14-C语言-小项目-通讯录
  4. 热式气体质量流量计检定规程_热式气体质量流量计基于热扩散原理
  5. 我通过了 Google 技术面试,所以你也能行!
  6. Vue-动态组件和插槽
  7. Spring思维导图(AOP篇)
  8. Codeforces Beta Round #1 B. Spreadsheets 模拟
  9. 51单片机智能小车寻循迹代码
  10. SRP记录_20190418
  11. FFmpeg 音视频截取
  12. design pattern Builder 生成器设计模式
  13. 一阶常微分方程(二)|全微分方程+线性方程+常数易变法+伯努力方程
  14. 内网和外网之间的通信
  15. 多投影-------边缘融合
  16. 全国大学生网络安全精英赛初赛(nisp一级)
  17. Zuul入门实战(完整版)
  18. CentOS7安装Nginx及配置
  19. linux 服务器的性能考核指标QPS、TPS、RT、Load、PV、UV
  20. 《小王子》中的经典语录(中英文对照)

热门文章

  1. div 页面框架布局
  2. 2021阳城二中高考成绩查询,晋城2021中考分数线预测
  3. 浮动带来的问题,以及清除浮动影响的方式
  4. 移动周刊第 184 期:Android 开发终极指南
  5. Nonlinear Schrodinger equations on the torus
  6. 小程序 微信位置详情页打开小程序
  7. 动态创建数组了解各种取值和取地址的问题以及感受内存地址
  8. 003--北大考研计算机--考研经验贴
  9. 第0章 计算机硬件与组成基础
  10. liunx关闭端口命令