IVI测试(注意:此页面计算校外流量)
最后更新于:2022-04-01 14:20:13
## 附上地址:[http://officetv.bupt.edu.cn/](http://officetv.bupt.edu.cn/)
## IVI测试(注意:此页面计算校外流量)
CCTV-1高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv1hd) [移动端](http://officetv.bupt.edu.cn/hls/cctv1hd.m3u8)
CCTV-3高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv3hd) [移动端](http://officetv.bupt.edu.cn/hls/cctv3hd.m3u8)
CCTV-5高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv5hd) [移动端](http://officetv.bupt.edu.cn/hls/cctv5hd.m3u8)
CCTV-5+高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv5phd) [移动端](http://officetv.bupt.edu.cn/hls/cctv5phd.m3u8)
CCTV-6高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv6hd) [移动端](http://officetv.bupt.edu.cn/hls/cctv6hd.m3u8)
CCTV-8高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv8hd) [移动端](http://officetv.bupt.edu.cn/hls/cctv8hd.m3u8)
CHC高清电影
[PC端](http://officetv.bupt.edu.cn/player.html?channel=chchd) [移动端](http://officetv.bupt.edu.cn/hls/chchd.m3u8)
北京卫视高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=btv1hd) [移动端](http://officetv.bupt.edu.cn/hls/btv1hd.m3u8)
北京文艺高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=btv2hd) [移动端](http://officetv.bupt.edu.cn/hls/btv2hd.m3u8)
北京体育高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=btv6hd) [移动端](http://officetv.bupt.edu.cn/hls/btv6hd.m3u8)
北京纪实高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=btv11hd) [移动端](http://officetv.bupt.edu.cn/hls/btv11hd.m3u8)
湖南卫视高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=hunanhd) [移动端](http://officetv.bupt.edu.cn/hls/hunanhd.m3u8)
浙江卫视高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=zjhd) [移动端](http://officetv.bupt.edu.cn/hls/zjhd.m3u8)
江苏卫视高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=jshd) [移动端](http://officetv.bupt.edu.cn/hls/jshd.m3u8)
东方卫视高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=dfhd) [移动端](http://officetv.bupt.edu.cn/hls/dfhd.m3u8)
安徽卫视高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=ahhd) [移动端](http://officetv.bupt.edu.cn/hls/ahhd.m3u8)
黑龙江卫视高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=hljhd) [移动端](http://officetv.bupt.edu.cn/hls/hljhd.m3u8)
辽宁卫视高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=lnhd) [移动端](http://officetv.bupt.edu.cn/hls/lnhd.m3u8)
深圳卫视高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=szhd) [移动端](http://officetv.bupt.edu.cn/hls/szhd.m3u8)
广东卫视高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=gdhd) [移动端](http://officetv.bupt.edu.cn/hls/gdhd.m3u8)
天津卫视高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=tjhd) [移动端](http://officetv.bupt.edu.cn/hls/tjhd.m3u8)
湖北卫视高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=hbhd) [移动端](http://officetv.bupt.edu.cn/hls/hbhd.m3u8)
山东卫视高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=sdhd) [移动端](http://officetv.bupt.edu.cn/hls/sdhd.m3u8)
重庆卫视高清
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cqhd) [移动端](http://officetv.bupt.edu.cn/hls/cqhd.m3u8)
CCTV-1综合
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv1) [移动端](http://officetv.bupt.edu.cn/hls/cctv1.m3u8)
CCTV-2财经
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv2) [移动端](http://officetv.bupt.edu.cn/hls/cctv2.m3u8)
CCTV-3综艺
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv3) [移动端](http://officetv.bupt.edu.cn/hls/cctv3.m3u8)
CCTV-4中文国际
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv4) [移动端](http://officetv.bupt.edu.cn/hls/cctv4.m3u8)
CCTV-5体育
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv5) [移动端](http://officetv.bupt.edu.cn/hls/cctv5.m3u8)
CCTV-6电影
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv6) [移动端](http://officetv.bupt.edu.cn/hls/cctv6.m3u8)
CCTV-7军事农业
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv7) [移动端](http://officetv.bupt.edu.cn/hls/cctv7.m3u8)
CCTV-8电视剧
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv8) [移动端](http://officetv.bupt.edu.cn/hls/cctv8.m3u8)
CCTV-9纪录
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv9) [移动端](http://officetv.bupt.edu.cn/hls/cctv9.m3u8)
CCTV-10科教
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv10) [移动端](http://officetv.bupt.edu.cn/hls/cctv10.m3u8)
CCTV-11戏曲
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv11) [移动端](http://officetv.bupt.edu.cn/hls/cctv11.m3u8)
CCTV-12社会与法
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv12) [移动端](http://officetv.bupt.edu.cn/hls/cctv12.m3u8)
CCTV-13新闻
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv13) [移动端](http://officetv.bupt.edu.cn/hls/cctv13.m3u8)
CCTV-14少儿
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv14) [移动端](http://officetv.bupt.edu.cn/hls/cctv14.m3u8)
CCTV-15音乐
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv15) [移动端](http://officetv.bupt.edu.cn/hls/cctv15.m3u8)
CCTV-NEWS
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cctv16) [移动端](http://officetv.bupt.edu.cn/hls/cctv16.m3u8)
北京卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=btv1) [移动端](http://officetv.bupt.edu.cn/hls/btv1.m3u8)
北京文艺
[PC端](http://officetv.bupt.edu.cn/player.html?channel=btv2) [移动端](http://officetv.bupt.edu.cn/hls/btv2.m3u8)
北京科教
[PC端](http://officetv.bupt.edu.cn/player.html?channel=btv3) [移动端](http://officetv.bupt.edu.cn/hls/btv3.m3u8)
北京影视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=btv4) [移动端](http://officetv.bupt.edu.cn/hls/btv4.m3u8)
北京财经
[PC端](http://officetv.bupt.edu.cn/player.html?channel=btv5) [移动端](http://officetv.bupt.edu.cn/hls/btv5.m3u8)
北京体育
[PC端](http://officetv.bupt.edu.cn/player.html?channel=btv6) [移动端](http://officetv.bupt.edu.cn/hls/btv6.m3u8)
北京生活
[PC端](http://officetv.bupt.edu.cn/player.html?channel=btv7) [移动端](http://officetv.bupt.edu.cn/hls/btv7.m3u8)
北京青年
[PC端](http://officetv.bupt.edu.cn/player.html?channel=btv8) [移动端](http://officetv.bupt.edu.cn/hls/btv8.m3u8)
北京新闻
[PC端](http://officetv.bupt.edu.cn/player.html?channel=btv9) [移动端](http://officetv.bupt.edu.cn/hls/btv9.m3u8)
北京卡酷少儿
[PC端](http://officetv.bupt.edu.cn/player.html?channel=btv10) [移动端](http://officetv.bupt.edu.cn/hls/btv10.m3u8)
深圳卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=sztv) [移动端](http://officetv.bupt.edu.cn/hls/sztv.m3u8)
安徽卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=ahtv) [移动端](http://officetv.bupt.edu.cn/hls/ahtv.m3u8)
河南卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=hntv) [移动端](http://officetv.bupt.edu.cn/hls/hntv.m3u8)
陕西卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=sxtv) [移动端](http://officetv.bupt.edu.cn/hls/sxtv.m3u8)
吉林卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=jltv) [移动端](http://officetv.bupt.edu.cn/hls/jltv.m3u8)
广东卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=gdtv) [移动端](http://officetv.bupt.edu.cn/hls/gdtv.m3u8)
山东卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=sdtv) [移动端](http://officetv.bupt.edu.cn/hls/sdtv.m3u8)
湖北卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=hbtv) [移动端](http://officetv.bupt.edu.cn/hls/hbtv.m3u8)
广西卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=gxtv) [移动端](http://officetv.bupt.edu.cn/hls/gxtv.m3u8)
河北卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=hebtv) [移动端](http://officetv.bupt.edu.cn/hls/hebtv.m3u8)
西藏卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=xztv) [移动端](http://officetv.bupt.edu.cn/hls/xztv.m3u8)
内蒙古卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=nmtv) [移动端](http://officetv.bupt.edu.cn/hls/nmtv.m3u8)
青海卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=qhtv) [移动端](http://officetv.bupt.edu.cn/hls/qhtv.m3u8)
四川卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=sctv) [移动端](http://officetv.bupt.edu.cn/hls/sctv.m3u8)
江苏卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=jstv) [移动端](http://officetv.bupt.edu.cn/hls/jstv.m3u8)
天津卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=tjtv) [移动端](http://officetv.bupt.edu.cn/hls/tjtv.m3u8)
山西卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=sxrtv) [移动端](http://officetv.bupt.edu.cn/hls/sxrtv.m3u8)
辽宁卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=lntv) [移动端](http://officetv.bupt.edu.cn/hls/lntv.m3u8)
厦门卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=xmtv) [移动端](http://officetv.bupt.edu.cn/hls/xmtv.m3u8)
新疆卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=xjtv) [移动端](http://officetv.bupt.edu.cn/hls/xjtv.m3u8)
东方卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=dftv) [移动端](http://officetv.bupt.edu.cn/hls/dftv.m3u8)
黑龙江卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=hljtv) [移动端](http://officetv.bupt.edu.cn/hls/hljtv.m3u8)
湖南卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=hunantv) [移动端](http://officetv.bupt.edu.cn/hls/hunantv.m3u8)
云南卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=yntv) [移动端](http://officetv.bupt.edu.cn/hls/yntv.m3u8)
江西卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=jxtv) [移动端](http://officetv.bupt.edu.cn/hls/jxtv.m3u8)
福建东南卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=dntv) [移动端](http://officetv.bupt.edu.cn/hls/dntv.m3u8)
浙江卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=zjtv) [移动端](http://officetv.bupt.edu.cn/hls/zjtv.m3u8)
贵州卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=gztv) [移动端](http://officetv.bupt.edu.cn/hls/gztv.m3u8)
宁夏卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=nxtv) [移动端](http://officetv.bupt.edu.cn/hls/nxtv.m3u8)
甘肃卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=gstv) [移动端](http://officetv.bupt.edu.cn/hls/gstv.m3u8)
重庆卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=cqtv) [移动端](http://officetv.bupt.edu.cn/hls/cqtv.m3u8)
兵团卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=bttv) [移动端](http://officetv.bupt.edu.cn/hls/bttv.m3u8)
旅游卫视
[PC端](http://officetv.bupt.edu.cn/player.html?channel=lytv) [移动端](http://officetv.bupt.edu.cn/hls/lytv.m3u8)
1. PC端链接播放需要您的浏览器支持Flash控件;
2. ivi测试用,该页面播放会计算校外流量
VLC 播放器 windows 测试直播流地址(支持多协议http、rtmp…)的个人推荐软件
最后更新于:2022-04-01 14:20:11
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac6107c15.jpg)
VLC多媒体播放器(最初命名为VideoLAN客户端)是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影音光盘及各类流式协议。它也能作为unicast或 multicast的流式服务器在IPv4或 IPv6的高速网络连接下使用。它融合了FFmpeg计划的解码器与libdvdcss程序库使其有播放多媒体文件及加密DVD影碟的功能。
Android 如何直播 RTMP 流
最后更新于:2022-04-01 14:20:09
在android上,视频/音频流直播是极少有人关注的一部分。每当我们讨论流媒体,RTMP(Real Time Messaging Protocol)是不可或缺的。RTMP是一个基本的视频/音频直播流协议,但是不幸的是Android标准的[vi](http://www.codeceo.com/article/vi-editor-guide.html "vi")deoView不支持RTMP的播放。因此,如果想在android上播放RTMP直播流,你必须使用支持RTMP协议的库。在本教程中我们将讨论如何通过使用安卓的 [Vitamio](https://www.vitamio.org/en/) 库播放由 RTMP 协议传输的流媒体。
![rtmp](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac607823a.png "")
### Android Vitamio 库
Vitamio是一个android和ios上基于[FFmpeg](https://www.ffmpeg.org/)的开源项目。Vitamio为我们提供了一个清洁、简单、全面、真实的硬件加速解码器和渲染器API,Vitamio是一个支持多种音视频格式 如 FLV, TS/TP, WMV, DivX, Xvid等多种标准格式的非常强大的库。所不同的是,它也支持类似.mkv和.srt嵌入和外挂字幕播放。但是它带有一个许可证,因此在使用它之前请先获得认证。在这个android RTMP例子中,我们不仅讨论RTMP直播流,而且也会讨论m3u8流(HLS),RTSP流和 MMS (Microsoft Media Stream)。首先让在我们的项目中引用Vitamio库。
#### 在Android Studio中引用Vitamio库的步骤如下:
1. 下载Vitamio bundle [https://github.com/yixia/VitamioBundle](https://github.com/yixia/VitamioBundle)
1. 解压并且在Android Studio上File->Import Module
1. 指定到VitamioBundle路径,选择vitamio文件夹 点击完成
1. 在build.gradle(Module: app)依赖部分添加依赖项目(‘:vitamio’)
1. 打开build.gradle (Module: vitamio) – 改变最小sdk版本为7
1. 不要忘记在manifest.xml中添加internet权限
1. 完成!
#### Android RTMP流
在讲述如何使用之前,让我们先了解下RTMP。Real Time Messaging Protocol (RTMP)是一个Adobe Systems所拥有的一个协议。该协议是Adobe公司拥有的开发音视频流的flash player。后来该协议的部分被公开,供公众使用。更多请查看[这里](http://en.wikipedia.org/wiki/Real_Time_Messaging_Protocol).这个协议大多用于IPTV和实时视频点播流,但它也用于其他领用。
在android上,标准的VideoView不支持RTMP播放。但WebView可以播放RTMP流。这解决了播放RTMP流的问题,但是我认为web apps 不能提供一个很好的界面和体验。因此这这个android RTMP例子中我们将运用第三方库-Vitamio 直播RTMP流的流媒体。在工程中引用Vitamio之后,请在你的layout文件添加Vitamio的VideoView:
activity_main.xml
~~~
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<io.vov.vitamio.widget.VideoView android:id="@+id/vitamio_videoView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
~~~
另外请编写你的activity如下:
MainActivity.java
~~~
package com.truiton.rtmpplayer;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import java.util.HashMap;
import io.vov.vitamio.LibsChecker;
import io.vov.vitamio.MediaPlayer;
import io.vov.vitamio.widget.MediaController;
import io.vov.vitamio.widget.VideoView;
public class MainActivity extends ActionBarActivity {
private static final String TAG = "MainActivity";
private String path;
//private HashMap<String, String> options;
private VideoView mVideoView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!LibsChecker.checkVitamioLibs(this))
return;
setContentView(R.layout.activity_main);
mVideoView = (VideoView) findViewById(R.id.vitamio_videoView);
path = "rtmp://rrbalancer.broadcast.tneg.de:1935/pw/ruk/ruk";
/*options = new HashMap<>();
options.put("rtmp_playpath", "");
options.put("rtmp_swfurl", "");
options.put("rtmp_live", "1");
options.put("rtmp_pageurl", "");*/
mVideoView.setVideoPath(path);
//mVideoView.setVideoURI(Uri.parse(path), options);
mVideoView.setMediaController(new MediaController(this));
mVideoView.requestFocus();
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.setPlaybackSpeed(1.0f);
}
});
}
}
~~~
虽然上面代码很清晰明了,但需要指出的是请修改你播放RTMP流的路径。在android上,有时可能使用带报头路径来播放RTMP流。幸运的是,Vitamio RTMP播放器也支持这种方式。因此,所有类型的RTMP流可以使用Vitamio库。上面的例子会是这个样子:
![Rtmpplayer](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac6095d61.png "")
#### Android RTSP流媒体
实时流协议(RTSP)通过多媒体服务器传输内容,例如YouTube使用RTSP流发布内容。关于RTSP流比较容易的部分是,它可以通过android标准的VideoView来完成,想了解更多,请参考我的[VideoView例子](http://www.truiton.com/2013/08/android-videoview-example-with-youtube-playback/)。
但是如果你使用Vitamio库,可以更好的播放RTSP流。事实上Vitamio也支持RTSP流的回播。和上面过程是一样的,包括Vitamio的VideoView在布局文件,并使用路径变量指定的RTSP url
~~~
mVideoView = (VideoView) findViewById(R.id.vitamio_videoView);
path = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov";
mVideoView.setVideoPath(path);
mVideoView.setMediaController(new MediaController(this));
mVideoView.requestFocus();
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.setPlaybackSpeed(1.0f);
}
});
~~~
#### Android m3u8 流媒体
“如何在android上播放m3u8视频”是android开发者最常见的问题之一。通过Http 协议进行视频流直播最简单的办法就是使用标准的 VideoView. 但只能在androi[D3](http://www.codeceo.com/article/javascript-d3-js.html "D3").0以上的设备上播放m3u8流。因为在Android 3.0引入HTTP/ HTTPS直播和HTTP/ HTTPS渐进式流媒体协议,在android3.1完全支持HTTPS。
如果你希望在早期的版本上实现支持android m3u8流的HTTP实时流媒体 (HLS)。应该考虑使用Vitamio库,这个库支持在android API7以上播放m3u8。使用方式,同样的在布局文件中使用Vitamio的VideoView,并指定的HTTP实时流媒体URL。
~~~
mVideoView = (VideoView) findViewById(R.id.vitamio_videoView);
path = "http://93.184.221.133/00573D/236/236-0.m3u8";
mVideoView.setVideoPath(path);
mVideoView.setMediaController(new MediaController(this));
mVideoView.requestFocus();
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.setPlaybackSpeed(1.0f);
}
});
~~~
Playing m3u8 stream on Android with Vitamio would look something like this:
在androi上使用Vitamio播放m3u8流效果如下:
![m3u8](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac60b0db7.png "")
#### Android MMS 流
Vitamio库是一个强大的库,还支持Microsoft媒体服务器(MMS)流中的播放。 MMS是网络流媒体协议,主要用于网络广播和电台直播。使用Vitamio用于在anroid的MMS流和其他协议没有什么不同。所有你需要做的只是更换路径变量指向一个MMS url:
~~~
mVideoView = (VideoView) findViewById(R.id.vitamio_videoView);
path = "mms://beotelmedia.beotel.net/studiob";
mVideoView.setVideoPath(path);
mVideoView.setMediaController(new MediaController(this));
mVideoView.requestFocus();
mVideoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.setPlaybackSpeed(1.0f);
}
});
~~~
### 结论
通过上面的讨论,可以确定地说,Vitamio是一个强大的多平台库(ios and android)。通过使用Vitamio库 能播放多种类型的视频格式和协议如RTMP, RTSP, HTTP Live, and HTTP渐进式流协议。另外一个很好的功能是,vitamio支持字幕和多音轨的播放。Vitamio的唯一的缺点是,它不是完全的开源。您可能需要购买许可证来使用它。
使用VideoView和MediaController进行视频播放
最后更新于:2022-04-01 14:20:06
一个视频播放的activity,可以直接拿过来用,比较简单,直接贴个[代码](http://www.xuebuyuan.com/ "代码")留作记录,效果如下:
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac6050e1e.jpg)
~~~
/**
* 视频播放的activity<br>
* 使用方法:<br>
* 1、AndroidManifest.xml中添加此activity<br>
* 2、Intent中存入待播放视频的URL,支持本地和网络<br>
* 3、启动这个activity<br>
* <br>
* example:<br>
* String url = "play url";<br>
* Intent intent = new Intent();<br>
* intent.setClass(this, VideoPlayActivity.class);<br>
* intent.putExtra(VideoPlayActivity.KEY_URL, url);<br>
* startActivity(intent);<br>
*
* @author ttworking
*
*/
public class VideoPlayActivity extends Activity implements OnPreparedListener, OnErrorListener {
public static final String KEY_URL = "view_url";
private static final String TAG = "VideoPlayActivity";
private static final int PLAY_RETURN = 2 * 1000; // 2 seconds
private static final String KEY_PLAY_POSITON = "paly_position";
private static final String TOAST_ERROR_URL = "Paly url is null, please check parameter:" + KEY_URL;
private static final String TOAST_ERROR_PLAY = "Paly error, please check url exist!";
private static final String DIALOG_TITILE = "奋力加载中,请稍后...";
private static String url;
private ProgressDialog progressDialog;
private MediaController mc;
private VideoView videoView;
private LinearLayout llMain;
private LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
url = getIntent().getStringExtra(KEY_URL);
if (url == null && savedInstanceState != null) {
url = savedInstanceState.getString(KEY_URL);
}
if (url == null) {
Toast.makeText(getApplicationContext(), TOAST_ERROR_URL, Toast.LENGTH_LONG).show();
finish();
return;
}
setTheme(android.R.style.Theme_NoTitleBar_Fullscreen);
videoView = new VideoView(this);
videoView.setVideoURI(Uri.parse(url));
videoView.requestFocus();
videoView.setOnPreparedListener(this);
videoView.setOnErrorListener(this);
mc = new MediaController(this);
mc.setAnchorView(videoView);
mc.setKeepScreenOn(true);
videoView.setMediaController(mc);
llMain = new LinearLayout(this);
llMain.setGravity(Gravity.CENTER_VERTICAL);
llMain.setOrientation(LinearLayout.VERTICAL);
llMain.setLayoutParams(params);
llMain.addView(videoView, params);
setContentView(llMain);
initDialog();
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
int palyPosition = videoView.getCurrentPosition();
if (palyPosition > PLAY_RETURN) {
palyPosition -= PLAY_RETURN;
}
outState.putInt(KEY_PLAY_POSITON, palyPosition);
outState.putString(KEY_URL, url);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
videoView.seekTo(savedInstanceState.getInt(KEY_PLAY_POSITON));
}
@Override
public void onPrepared(MediaPlayer mp) {
progressDialog.cancel();
videoView.start();
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.d(TAG, "onError:" + url);
Toast.makeText(getApplicationContext(), TOAST_ERROR_PLAY + "\n" + url, Toast.LENGTH_LONG).show();
progressDialog.cancel();
finish();
return true;
}
private void initDialog() {
progressDialog = new ProgressDialog(this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
progressDialog.setMessage(DIALOG_TITILE);
progressDialog.setCancelable(false);
progressDialog.show();
}
}
~~~
使用Vitamio 播放网络视频的注意事项
最后更新于:2022-04-01 14:20:04
总的步骤:
一:导入vitamio_lib包
二:xml布局中的videoView要替换
三:java文件中的所有包导入的都是vitamio_lib下的东西
四:在java文件的setContentView前要加判断!!!
五:在清单文件中要加入io.vov.vitamio.activity.InitActivity的声明!!!
试例:
二:xml布局:
~~~
<io.vov.vitamio.widget.VideoView
android:id="@+id/vv"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true" />
~~~
三:导入包:
~~~
import io.vov.vitamio.LibsChecker;
import io.vov.vitamio.MediaPlayer;
import io.vov.vitamio.MediaPlayer.OnPreparedListener;
import io.vov.vitamio.widget.MediaController;
import io.vov.vitamio.widget.VideoView;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
~~~
四:加判断:
~~~
if (!LibsChecker.checkVitamioLibs(this))
return;
~~~
五:清单文件中加声明:
~~~
<activity
android:name="io.vov.vitamio.activity.InitActivity"
android:configChanges="orientation|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
android:launchMode="singleTop"
android:theme="@android:style/Theme.NoTitleBar"
android:windowSoftInputMode="stateAlwaysHidden" />
~~~
播放RTMP协议的流媒体的两种选择
最后更新于:2022-04-01 14:20:02
播放网络视频,通常解析库我们可以有两个选择 FFMPEG 或者 vitamio。
### 什么FFMPEG?
官网地址: [地址](http://ffmpeg.org/)
FFmpeg是一套可以用来记录、转换数字音频、视频,并能将其转化为流的开源计算机程序。采用LGPL或GPL许可证。它提供了录制、转换以及流化音视频的完整解决方案。它包含了非常先进的音频/视频编解码库libavcodec,为了保证高可移植性和编解码质量,libavcodec里很多codec都是从头开发的。
支持的编码 源自FFmpeg项目组的两个视频编码 Snow FFV1
支持的格式 ASF、AVI、BFI、IFF、RL2、FLV、MXF、Material eXchange Format、SMPTE、377M、Matroska、Maxis XA、MSN Webcam stream、MPEG transport stream、TXD、OMA、GXF、General eXchange Format、SMPTE、360M、mov、mp4、m4a、3gp。
### 什么是Vitamio?
官网地址: [地址](https://www.vitamio.org/)
github地址:[地址](https://github.com/yixia/VitamioBundle)
Vitamio是一款 Android 与 iOS 平台上的全能多媒体开发框架,全面支持硬件解码与 GPU 渲染。
Vitamio能够流畅播放720P甚至1080P高清MKV,FLV,MP4,MOV,TS,RMVB等常见格式的视频,还可以在Android 与 iOS 上跨平台支持 MMS, RTSP, RTMP, HLS(m3u8) 等常见的多种视频流媒体协议,包括点播与直播。
Vitamio支持各种常见的流媒体协议,可以点播或者直播音频和视频,例如如下常见协议均能无缝支持:
MMS、RTSP (RTP, SDP)、RTMP、HTTP progressive streaming、HLS - HTTP live streaming (M3U8)
音频和视频格式
Vitamio使用了 FFmpeg 做为媒体解析器和最主要的解码器,同时开发了针对不同移动平台的硬解码方案,能够完美支持 H.264/AVC、H.263、MPEG4 等常见的视频编码,覆盖上百种多媒体格式。下表只是一些最常见的视频格式支持,除特殊标明,全部支持硬件加速:
DivX/Xvid、WMV (一般只有软解码)、FLV、TS/TP、RMVB (只有软解码)、MKV、MOV、M4V、AVI、MP4、3GP。
Vitamio 项目托管在Github 上面,,这里有很多公司的开源项目,其中:
1、VitamioBundle是Vitamio核心插件,(大家可以搜一下"Android Library"这个关键字,和jar差不多的用途),可以方便集成到项目中。
2、VitamioDemo是Vitamio的官方例子。
使用方式
1.导入。通过github下载VitamioBundle。下载回来后大家可能发现没有.project工程文件,可以通过File-> Import -> Android -> Existing Android Code Into Workspace来导入工程,然后改一下工程名称即可。
2、将VitamioBundle工程作为Android Library引入Demo工程使用即可。
什么是RTMP协议
最后更新于:2022-04-01 14:20:00
### RTMP实时消息传送协议协议概述
RTMP(Real Time Messaging Protocol)实时消息传送协议是[Adobe](http://baike.baidu.com/view/7578.htm) Systems公司为Flash播放器和服务器之间音频、视频和数据传输 开发的开放协议。
它有多种变种:
1)RTMP工作在TCP之上,默认使用端口1935;
2)RTMPE在RTMP的基础上增加了加密功能;
2)RTMPT封装在[HTTP请求](http://baike.baidu.com/view/641736.htm)之上,可穿透[防火墙](http://baike.baidu.com/view/3067.htm);
3)RTMPS类似RTMPT,增加了TLS/SSL的安全功能;
###
### 协议详细介绍
[编辑]()
RTMP协议(Real Time Messaging Protocol)是被Flash用于对象,视频,音频的传输.这个协议建立在TCP协议或者[轮询](http://baike.baidu.com/view/1870084.htm)[HTTP协议](http://baike.baidu.com/view/70545.htm)之上.
RTMP协议就像一个用来装数据包的容器,这些数据既可以是AMF格式的数据,也可以是FLV中的视/音频数据.
一个单一的连接可以通过不同的通道传输多路网络流.这些通道中的包都是按照固定大小的包传输的.
网络连接(Connection)
一个Actionscript连接并播放一个流的简单代码:
~~~
var videoInstance:Video = your_video_instance;
var nc:NetConnection = new NetConnection();
var connected:Boolean = nc.connect("rtmp:/localhost/myapp");
var ns:NetStream = new NetStream(nc);
videoInstance.attachVideo(ns);
ns.play("flvName");
~~~
默认端口为1935
###
### 握手请求及应答
[编辑]()
Client → Server :向服务器发出握手请求.这不属于协议包一部分,该握手请求第一个字节为(0×03),其后跟着1536个字节.尽管看上去这部分的内容对于RTMP协议来说并不是至关重要的,但也不可随意对待.
Server → Client :服务器向客户端回应握手请求.这部分的数据仍然不属于RTMP协议的部分.该回应的起始字节仍然为(0x03),但是后边跟着两个长度为1536个字节(一共为3072字节 )的包块.第一个1536块看上去似乎可以是任意内容,甚至好像可以是Null都没有关系.第二个1536的代码块,是上一步客户端向服务器端发送的握手请求的内容.
Client→Server:把上一步服务器向客户端回应的第二块1536个字节的[数据块](http://baike.baidu.com/view/702806.htm).
至此客户端与服务器端的握手结束,下面将发送RTMP协议的包内容.
Client → Server :向服务器发送连接包.
Server → Client :服务器回应.
... .... 等等... ...
RTMP 数据类型
0×01 Chunk Size changes the chunk size for packets
0×02 Unknown anyone know this one?
0×03 Bytes Read send every x bytes read by both sides
0×04 Ping ping is a stream control message, has subtypes
0×05 Server BW the servers downstream bw
0×06 Client BW the clients upstream bw
0×07 Unknown anyone know this one?
0×08 Audio Data packet containing audio
0×09 Video Data packet containing video data
0x0A - 0×11 Unknown anyone know?
0×12 Notify an invoke which does not expect a reply
0×13 Shared Object has subtypes
0×14 Invoke like remoting call, used for stream actions too.
Shared Object 数据类型
0×01 Connect
0×02 Disconnect
0×03 Set Attribute
0×04 Update Data
0×05 Update Attribute
0×06 Send Message
0×07 Status
0×08 Clear Data
0×09 Delete Data
0x0A Delete Attribute
0x0B
Initial Data
RTMP包结构
RTMP包 包含一个固定长度的包头和一个最长为128字节的包体.包头可以是下面4种长度的任意一种:12, 8, 4, or 1 byte(s).
第一个字节的前两个Bit很重要,它决定了包头的长度.它可以用[掩码](http://baike.baidu.com/view/68.htm)0xC0进行"与"计算.下面的表格罗列了可能的包头长度:Bits Header Length
00 12 bytes
01 8 bytes
10 4 bytes
11 1 byte
其实RTMP包结构就是使用了AMF格式.
下面是一个关于客户端向服务器端发送流的流程:
Client→Server :发送一个创建流的请求.
Server→Client :返回一个表示流的索引号.
Client→Server :开始发送.
Client→Server :发送视音频数据包(这些包在同一个频道(channel)并用流的索引号来唯一标识).
### RTMP包结构:
[![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac5fec3a1.png)](http://static.oschina.net/uploads/space/2015/0513/212433_iB2d_112731.png)
### 握手
[![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac6034f06.png)](http://static.oschina.net/uploads/space/2015/0513/213027_YAPA_112731.png)
### 参考:
[http://www.pigg.co/rtmp-protocol-handshake.html](http://www.pigg.co/rtmp-protocol-handshake.html)
[https://github.com/simple-rtmp-server/srs/wiki/v1_CN_RTMPHandshake](https://github.com/simple-rtmp-server/srs/wiki/v1_CN_RTMPHandshake)
http://en.wikipedia.org/wiki/Real_Time_Messaging_Protocol
Android使用VideoView播放视频
最后更新于:2022-04-01 14:19:57
VideoView 是Android 自带的可以播放视频的控件。
它的使用方法也比较简单,相当于是surfaceview+mediaplayer 两者的集合体。
对于一个控件的使用 无外乎 三步:
1. 初始化
2 设置数据、添加监听事件的方法
3.在监听方法中 进行处理事件。
对于VideoView来说也不例外, 首先我们可以再xml 布局中引用videoview。
~~~
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<VideoView
android:id="@+id/videoView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"/>
</RelativeLayout>
~~~
接下来在相关界面进行初始化设置:
~~~
/**
* 准备播放工作
*/
private void initVideoView() {
String uri = ConfigManage.URL_SPLASH;
videoView.setVideoURI(Uri.parse(uri));
videoView.setOnPreparedListener(this);
// 设置全屏
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT,
RelativeLayout.LayoutParams.FILL_PARENT);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
videoView.setLayoutParams(layoutParams);
videoView.setOnCompletionListener(this);
}
~~~
这里设置了 onPrepareListener() 与 OnCompletionListener() 因此我们实现这两个方法
~~~
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
videoView.start();
videoView.requestFocus();
}
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
goToMainActivity();
}
~~~
下面是具体效果,还不错吧,播放起来还是很流畅的,
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac5f8e926.jpg)
但是Video播放视频时有格式限制的,应该是仅仅只有 3gp与 MP4 可用, 播放网络视频需要添加联网权限。
完整代码没有做成Demo,需要的可以自己去摘,在项目中的SplashActivity:[https://github.com/CodingForAndroid/appone/](https://github.com/CodingForAndroid/appone/)
播放视频的框架Vitamio的使用问题
最后更新于:2022-04-01 14:19:55
原文:http://blog.csdn.net/sunalongl/article/details/30252127?utm_source=tuicool&utm_medium=referral
以前用过这个牛逼的框架,后来又随意搞了下,发现播放不了视频了,搞了老半天才搞好,今天又随便整了下,发现又不行了,我勒个插!
现在终于又搞出来了,发现我总是把步骤搞错或少写了些东西
总的步骤:
一:导入vitamio_lib包
二:xml布局中的videoView要替换
三:java文件中的所有包导入的都是vitamio_lib下的东西
四:在java文件的setContentView前要加判断!!!<易遗忘>
五:在清单文件中要加入io.vov.vitamio.activity.InitActivity的声明!!!<易遗忘>
示例:
一:导包。。。。
二:xml布局:
~~~
1. <io.vov.vitamio.widget.VideoView
1. android:id="@+id/vv"
1. android:layout_width="fill_parent"
1. android:layout_height="fill_parent"
1. android:layout_centerInParent="true" />
~~~
三:导入包:
~~~
1. import io.vov.vitamio.LibsChecker;
1. import io.vov.vitamio.MediaPlayer;
1. import io.vov.vitamio.MediaPlayer.OnPreparedListener;
1. import io.vov.vitamio.widget.MediaController;
1. import io.vov.vitamio.widget.VideoView;
1. import android.annotation.SuppressLint;
1. import android.app.Activity;
1. import android.os.Bundle;
1. import android.view.View;
~~~
四:加判断:
~~~
1. if (!LibsChecker.checkVitamioLibs(this))
1. return;
~~~
五:清单文件中加声明:
~~~
1. <activity
1. android:name="io.vov.vitamio.activity.InitActivity"
1. android:configChanges="orientation|screenSize|smallestScreenSize|keyboard|keyboardHidden|navigation"
1. android:launchMode="singleTop"
1. android:theme="@android:style/Theme.NoTitleBar"
1. android:windowSoftInputMode="stateAlwaysHidden" />
~~~
公司(视频 社交)项目分享
最后更新于:2022-04-01 14:19:53
最近公司工作比较轻松,就把以前的项目 拿来整理下。以前公司做视频社交这一块,类似于YY直播。
### 展示
##### **先来个动态图**
![这里写图片描述](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac5d8d6f5.jpg "")
##### **再简单看一下主要界面**
首页第一个界面,这里可以看美女,看直播
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac5de32ec.jpg "")
这是任务列界面,可以领取每日任务,任务分成长 和推荐
![](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac5e1907b.jpg "")
好友列表
![这里写图片描述](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac5e35fb7.jpg "")
用户的个人中心页
![这里写图片描述](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac5e53962.jpg "")
直播间
![这里写图片描述](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac5e76ea7.jpg "")
用户的个人中心页
![这里写图片描述](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac5e9cb05.jpg "")
充值方式页
![这里写图片描述](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac5ebdecd.jpg "")
银联支付页
![这里写图片描述](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac5ed5d72.jpg "")
### 项目组成
这个项目主要的重点就两个地方,看视频,和 与主播互动。
整个视频流是用RTMP协议的,文字聊天走的是openfire+asmack .
PS:整个项目,我们产品设计的很不错的,只是我水平有限,有些功能 实现不了!
再介绍下,整个项目都用到了什么?
程序框架:SlidingMenu+Viewpager+fragment
请求服务器: asynchttpclient
解析数据:Gson
消息推送: Jpush
页面数据分析: Umeng
充值方式: alipay +银联+yeepay+短信充值
图片缓存: afinal
自定义view: Pulltoresfresh+拼音排序联系人+horizontallistview+verticalviewpager…
![这里写图片描述](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac5f09528.jpg "")
另,我把公司的项目写出来,是因为公司的服务器停掉了,所以,一些数据,是我自己抓出其他应用里面的(抓取数据的方法,在上面一篇文章里)….
首先就是整个项目最下面是mainactivity,这个大家是都有共识的,在mainactivity 上面 我们就要 引入slidingmenu,
关于slidingmenu的下载,就不介绍了,这里直接拿来用
包结构比较清晰
![这里写图片描述](https://docs.gechiui.com/gc-content/uploads/sites/kancloud/2016-04-06_5704ac5f72481.jpg "")
,
整个项目首先,由splashactivity 欢迎界面 ,进行检查,然后跳转到mainactivity,mainactivity 中包含slidingmenu,slidingmenu的中间界面 添加了viewpager,viewpager 里面添加了四个fragment。
由于默认v4包里的viewpager 会默认混存数据,即使你设置了setOffscreenPageLimit(0),所以这里替换掉原生的v4包,并且通过fragment 的 setuservisibilityhint 方法来,控制 fragment 界面的动态刷新。
主界面的第一个fragment ,也就是约美女的界面,通过fragmenttabhost,来实现约美女,和看直播的切换。
在约美女中,就是一个简单地pulltorefreshlistview,适配了一个item.点击item 进入用户的个人中心, 个人中心 顶部 是个人的宣传适配,下面,是用户自己上传的 公开专辑,或者私密专辑。可以点赞,关注他。
做任务界面是有两种任务,一种是 每日任务,就是 登陆,签到,另一种是下载app 得积分任务。 下载app 可以控制 下载 暂停。
在我的关注界面。是你关注的好友,这个跟微信的联系人控件是一样的。首字母排序,用到了比较器。
首先 把汉字,对应首字母提取出来,然后与A-Z 排序。以及特殊字符~。
### 基本代码
整个项目 基本框架 简单描述下
在MainActiviy中初始化 slidingmenu。MainActivity 布局文件
`<?xml version="1.0" encoding="utf-8"?>
<com.os.slidingmenu.SlidingMenu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:sliding="http://schemas.android.com/apk/res-auto"
android:id="@+id/slidingmenu"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
sliding:behindOffset="60dp"
sliding:fadeEnabled="true"
sliding:mode="left"
sliding:secondaryShadowDrawable="@drawable/sliding_shadow_right"
sliding:shadowDrawable="@drawable/sliding_shadow_left"
sliding:shadowWidth="10dp"
sliding:touchModeAbove="fullscreen"
sliding:touchModeBehind="margin" />
`
MainActivity这个类进行初始化。
~~~
package com.os.activity;
import java.lang.ref.WeakReference;
import com.os.activity.base.BaseFragmentActivity;
import com.os.activity.base.BaseSlidingFragment;
import com.os.activity.sliding.LeftFragment;
import com.os.activity.sliding.RightFragment;
import com.os.slidingmenu.R;
import com.os.slidingmenu.SlidingMenu;
import com.os.ui.MainHallFragment;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
public class MainActivity extends BaseFragmentActivity {
private Fragment mCurFragment;
public static SlidingMenu mSlidingMenu;
private Handler handler = new MyHandler(this);
private static class MyHandler extends Handler {
private final WeakReference<MainActivity> mActivity;
public MyHandler(MainActivity activity) {
mActivity = new WeakReference<MainActivity>(activity);
}
@Override
public void handleMessage(Message msg) {
MainActivity activity = mActivity.get();
if (activity == null) {
return;
}
activity.handleMsg(msg);
}
}
private void handleMsg(Message msg) {
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
if (savedInstanceState != null) {
mCurFragment = getSupportFragmentManager().getFragment(savedInstanceState, "mCurContent");
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState, "mCurContent", mCurFragment);
}
private void initViews() {// 通过id 找到slidingmenu
mSlidingMenu = (SlidingMenu) findViewById(R.id.slidingmenu);
mSlidingMenu.setMenu(R.layout.sliding_left_frame);//给slidingmenu 添加左边的布局
if (getFragmentByTag(LeftFragment.class) == null) {//添加左边fragment
getSupportFragmentManager().beginTransaction().add(R.id.left_frame, new LeftFragment(), LeftFragment.class.getName()).commit();
}
mSlidingMenu.setContent(R.layout.sliding_center_frame);//添加一个空布局,后面承载 中间的fragment
mSlidingMenu.setSecondaryMenu(R.layout.sliding_right_frame);//添加右面的布局,添加右边的fragment
if (getFragmentByTag(RightFragment.class) == null) {
getSupportFragmentManager().beginTransaction().add(R.id.right_frame, new RightFragment(), RightFragment.class.getName()).commit();
}
if (mCurFragment != null) {
postSwitchFragment();
}
mSlidingMenu.setTouchModeAbove(SlidingMenu.TOUCHMODE_MARGIN);//设置滑动模式,边缘 还是整个界面
}
/**
* slidingMenu中的内容Fragment切换(左侧菜单触发)
*
* @param clazz
*/
public void switchCenterFragment(Class<? extends Fragment> clazz) {
try {
if (mSlidingMenu == null) {
removeAllFragments();
return;
}
boolean isInit = false;
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
Fragment userFragment = fm.findFragmentByTag(clazz.getName());
if (userFragment == null) {
isInit = true;
try {
userFragment = clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
if (mCurFragment != null && mCurFragment != userFragment) {
ft.hide(mCurFragment);
}
if (!userFragment.isAdded() && isInit) {
ft.add(R.id.center_frame, userFragment, clazz.getName());
} else {
ft.show(userFragment);
}
ft.commitAllowingStateLoss();
mCurFragment = userFragment;
if (MainHallFragment.class.getName().equals(clazz.getName())) {
mSlidingMenu.setMode(SlidingMenu.LEFT_RIGHT);
if (!isInit) {
((MainHallFragment) userFragment).postScrollTop();
}
} else {
mSlidingMenu.setMode(SlidingMenu.LEFT_RIGHT);
}
postShowContent(200);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* lidingMenu中的内容Fragment内容过滤(右侧菜单触发)
*
* @param clazz
* @param type
*/
public void filterCenterFragment(Class<? extends BaseSlidingFragment> clazz, int type) {
BaseSlidingFragment userFragment = (BaseSlidingFragment) getFragmentByTag(clazz);
if (userFragment != null) {
userFragment.filter(type);
}
if (mSlidingMenu != null)
mSlidingMenu.showContent();
}
/**
* 延迟切换Fragment
*/
private void postSwitchFragment() {
handler.postDelayed(new Runnable() {
@Override
public void run() {
switchCenterFragment(mCurFragment.getClass());
}
}, 50);
}
/**
* 清除FragmentManager中所有Fragment
*/
private void removeAllFragments() {
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
for (int i = 0; i < LeftFragment.FRAGMENTS_CLASSES.length; i++) {
Fragment fragment = getFragmentByTag(LeftFragment.FRAGMENTS_CLASSES[i].getName());
if (fragment != null) {
ft.remove(fragment);
}
}
ft.commitAllowingStateLoss();
}
/**
* 延时mSlidingMenu.showContent()
*
* @param delayMillis 延时时间 单位毫秒
*/
private void postShowContent(long delayMillis) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (mSlidingMenu!=null && !MainActivity.this.isFinishing()) {
mSlidingMenu.showContent();
}
}
}, delayMillis);
}
}
~~~
左边的fragment
~~~
package com.os.activity.sliding;
import java.util.Arrays;
import com.os.activity.MainActivity;
import com.os.activity.base.BaseSlidingFragment;
import com.os.slidingmenu.R;
import com.os.ui.FollowFragment;
import com.os.ui.MainHallFragment;
import com.os.ui.RankFragment;
import android.app.ProgressDialog;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;
public class LeftFragment extends BaseSlidingFragment {
private final static int MENU_NORMAL_ICONS[] = { R.drawable.sliding_livehall_icon_normal,
R.drawable.sliding_follow_icon_normal, R.drawable.sliding_rank_icon_normal};
private final static int MENU_CHECKED_ICONS[] = { R.drawable.sliding_livehall_icon_checked,
R.drawable.sliding_follow_icon_checked, R.drawable.sliding_rank_icon_checked };
public final static Class[] FRAGMENTS_CLASSES = { MainHallFragment.class, FollowFragment.class,
RankFragment.class};//左侧切换显示中间的三个界面
private View[] mMenuLayouts;
private ImageView[] mMenuIcons;
private TextView[] mMenuTexts;
private Bitmap mLoadingBitmap;
private int mCurrentIndex = -1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sliding_left);
setData();
changeMenuByClass(MainHallFragment.class);//默认中间的界面显示的是这个MainHallFragment
}
@Override
public void initViews() {
mMenuLayouts = new View[] { findViewById(R.id.menu_livehall_layout),
findViewById(R.id.menu_follow_layout), findViewById(R.id.menu_rank_layout) };
mMenuIcons = new ImageView[] {
(ImageView) findViewById(R.id.menu_livehall_icon), (ImageView) findViewById(R.id.menu_follow_icon), (ImageView) findViewById(R.id.menu_rank_icon) };
mMenuTexts = new TextView[] {
(TextView) findViewById(R.id.menu_livehall_text), (TextView) findViewById(R.id.menu_follow_text), (TextView) findViewById(R.id.menu_rank_text),};
}
@Override
public void addListener() {
for (int i = 0; i < mMenuLayouts.length; i++) {
mMenuLayouts[i].setTag(i);
mMenuLayouts[i].setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
int index = (Integer) v.getTag();
changeMenuByIndex(index);
}
});
}
}
private void setData() {
}
/**
* 通过索引改变Menu
*
* @param index
*/
@SuppressWarnings("unchecked")
private void changeMenuByIndex(int index) {
Class<? extends Fragment> clazz = null;
if (mCurrentIndex != index) {
clearMenu();
setMenuChecked(index);
}
clazz = FRAGMENTS_CLASSES[index];
getFragmentActivity(MainActivity.class).switchCenterFragment(clazz);
mCurrentIndex = index;
}
/**
* 通过Fragment类改变menu
*
* @param clazz
*/
public void changeMenuByClass(Class<? extends Fragment> clazz) {
int index = Arrays.asList(FRAGMENTS_CLASSES).indexOf(clazz);
if (index != -1) {
changeMenuByIndex(index);
}
}
@SuppressWarnings("deprecation")
private void clearMenu() {
for (int i = 1; i <= mMenuLayouts.length; i++) {
mMenuLayouts[i-1].setBackgroundDrawable(null);
mMenuIcons[i - 1].setImageResource(MENU_NORMAL_ICONS[i - 1]);
mMenuTexts[i - 1].setTextColor(getResources().getColor(R.color.gray7));
}
}
private void setMenuChecked(int index) {
// if (index == 0) {
// return;
// }
if (index != 1 && index != 2) {
mMenuLayouts[index].setBackgroundResource(R.drawable.sliding_menu_checked_bg);
}
mMenuIcons[index ].setImageResource(MENU_CHECKED_ICONS[index ]);
mMenuTexts[index ].setTextColor(getResources().getColor(R.color.white));
}
@Override
public void onDestroy() {
if (mLoadingBitmap != null && !mLoadingBitmap.isRecycled()) {
mLoadingBitmap.recycle();
mLoadingBitmap = null;
}
super.onDestroy();
}
}
~~~
主要就是 oncreate 中 初始化 刚启动应用后中间显示的fragment 是 MainHallFragment.
视频时RTMP 协议,解码用的ffmpeg. 代码就不贴了,在工程的jni 目录下,都有注释。
聊天的代码 聊天室界面是 ChatroomActivity.
这是 一初始化MultiUserChat 聊天室对象的代码,具体代码 ,在这个类里面。
~~~
new Thread() {
public void run() {
try {
Thread.sleep(1 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
int count = 0;
boolean isRandom = false;
while (count <= 10 && !create_flag) {
count++;
try {
if (mHostInfo != null) {
mUserNickName = getNickName(isRandom);
muc = ConnectionUtils.getMultiUserChat(mHostInfo.room_id, mHostInfo.room_service, mUserNickName, mPassword, ChatroomActivity.this);
if (muc != null) {
create_flag = true;
// 创建聊天室成功,监听聊天室返回的消息
// 监听消息
muc.addMessageListener(packetListener);
// muc.addParticipantListener(participantListener);
muc.addParticipantStatusListener(statusListener);
muc.addUserStatusListener(userStatusListener);
mHandler.sendEmptyMessageDelayed(9, 500);
} else {
create_flag = false;
}
} else {
create_flag = false;
}
// } else {
//
// }
} catch (NotFoundException e) {
e.printStackTrace();
} catch (SameException e) {// 昵称重复
isRandom = true;
} catch (BannedException e) {// 禁止加入房间
sendBandHandle(15);
return;
} catch (XMPPException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
~~~
前言
最后更新于:2022-04-01 14:19:50
> 原文出处:[Android流媒体播放](http://blog.csdn.net/column/details/rtmp-android.html)
> 作者:[u011733020](http://blog.csdn.net/u011733020)
**本系列文章经作者授权在看云整理发布,未经作者允许,请勿转载!**
# Android流媒体播放
> Android流媒体播放、RTMP协议、FFMPEG、Vitamio。