基于Android系統(tǒng)的設(shè)備上投放廣告視頻,比如:地鐵廣告屏、自助服務(wù)機器上的廣告位,取號機廣告等。
最近兩天做了一個叫號機端的系統(tǒng),內(nèi)部有一塊循環(huán)播放視頻廣告的處理,于是乎有了此篇小結(jié)
先來了解下視頻廣告的幾個的特點
一、網(wǎng)絡(luò)視頻緩存處理
二、循環(huán)播放功能
三、動態(tài)更新視頻廣告
四、時效性的保證
一、網(wǎng)絡(luò)視頻緩存處理
顯然不可能每次播放都去加載網(wǎng)絡(luò),太耗費流量,哪怕是WIFI 情況下,也需要緩存起來。
這里可以使用通過第三方框架 AndroidVideoCache
1、添加依賴
implementation 'com.danikula:videocache:2.7.0’
2、初始化代理配置
public static HttpProxyCacheServer proxy; //視頻緩存代理
//創(chuàng)建視頻播放緩存代理
proxy = new HttpProxyCacheServer.Builder(this)
.maxCacheSize(1024 * 1024 * 1024) //1Gb 緩存
.maxCacheFilesCount(5)//最大緩存5個視頻
.build();
二、循環(huán)處理 根據(jù)多個視頻的數(shù)量,使用 取模的方式 進行遞歸調(diào)用
核心代碼
public void playVideoOne() {
int urlSize = urlList.size();
index = index % urlSize;
MediaController mediaController = new MediaController(getThis());
//緩存起來這個 url 視頻 提供緩存文件的名稱默認情況下,AndroidVideoCache使用視頻網(wǎng)址的MD5作為文件名
// String proxyUrl = App.proxy.getProxyUrl("[http://jzvd.nathen.cn/63f3f73712544394be981d9e4f56b612/69c5767bb9e54156b5b60a1b6edeb3b5-5287d2089db37e62345123a1be272f8b.mp4](http://jzvd.nathen.cn/63f3f73712544394be981d9e4f56b612/69c5767bb9e54156b5b60a1b6edeb3b5-5287d2089db37e62345123a1be272f8b.mp4)");
String proxyUrl = App.proxy.getProxyUrl(urlList.get(index));
videoView.setMediaController(mediaController);//如果設(shè)置Controller 點擊時會有可交互模式,暫停快進或快退;不設(shè)置的話更適用于廣告,不可交互,只進行展示
videoView.setVideoPath(proxyUrl); //為videoview設(shè)置播放路徑
videoView.start();
videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mPlayer) {
// mPlayer.start();
// //循環(huán)播放
// mPlayer.setLooping(true);
index++;
playVideoOne();// 監(jiān)聽視頻一的播放完成事件,播放完畢就播放視頻二 遞歸
}
});
}
TIps:
1、如果是單個視頻進行循環(huán)播放可在
videoView.setOnPreparedListener();
videoView.setOnCompletionListener();
//這兩個方法回調(diào)中調(diào)用 ,均可達到循環(huán)播放單一視頻的效果,建議寫在 onCompletion 之后
mPlayer.start();
//循環(huán)播放
mPlayer.setLooping(true);
2、播放網(wǎng)絡(luò)地址 Api
videoView.setVideoURI(Uri.parse("xxx"));//也可以達到播放網(wǎng)絡(luò)視頻的效果,
因為videoView.setVideoPath 內(nèi)部調(diào)用的就是 videoView.setVideoURI
3、Xml 使用VideoView展示
<VideoView
android:id="@+id/videoView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
4、播放異常時候?qū)ideoView 的處理
videoView.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
videoView.stopPlayback(); //播放異常,則停止播放,防止彈窗使界面阻塞
return true;
}
});
5、關(guān)于 ViewView 的暫停和繼續(xù)從上一次的位置進行播放
在OnPause你可以得到當前的位置。
stopLength=mVideoView.getCurrentPosition();
mVideoView.pause()
在OnResume()中使用。
mVideoView.seekTo(stopLength);
mVideoView.start()
如果給 ViedeView 設(shè)置 setVisibility GONE 隱藏的話,使用上面的方式進行恢復播放 則會從頭開始播放!
場景:
根據(jù)一個遠程服務(wù)器端的通知,在廣告機上正在播放視頻時 切換展示一個通知頁面覆蓋正在播放的視頻區(qū)域。
解決方案:
可以使用 重疊布局「FrameLayout」的方式,ViedoView 放在圖層底部,一直播放。動態(tài)控制 VideoView 上面的通知頁面 隱藏展示??芍苯硬恍枰獙ieoView 做暫停和恢復的操作。 當然你也可以處理暫停再繼續(xù)播放。記得不允許給ViedeView設(shè)置隱藏!
6、調(diào)用 seekTo 方法跳轉(zhuǎn)不準的問題
在seekTo完成的監(jiān)聽方法中再執(zhí)行 VideoView.start();
// 設(shè)置 VideoView 的 OnPrepared 監(jiān)聽,拿到 MediaPlayer 對象。
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
//設(shè)置 MediaPlayer 的 OnSeekComplete 監(jiān)聽
mp.setOnSeekCompleteListener(new MediaPlayer.OnSeekCompleteListener() {
@Override
public void onSeekComplete(MediaPlayer mp) {
// seekTo 方法完成時的回調(diào)
if(isPause){
videoView.start();
isPause = false;
}
}
});
}
});
可參考 http://www.itdecent.cn/p/f51b2febcfd2
7、視頻切換在后臺之后再次進入頁面重新播放處理
/**
* 在onResume()方法控制視頻繼續(xù)播放
*/
@Override
protected void onResume() {
super.onResume();
if (videoView != null) {
videoView.seekTo(videoCurrentPosition);
videoView.start();
}
}
/**
* onPause() 控制視頻暫停播放
*/
@Override
protected void onPause() {
super.onPause();
if (videoView != null) {
videoCurrentPosition = videoView.getCurrentPosition();
videoView.pause();
}
}
三、動態(tài)更新廣告
方式有很多
1、接收推送時候重新做請求
2、定時輪詢或者指定時間請求最新,要想保證時效性可在的鏈接地址后面做 日期截取處理判斷
四、時效性的保證
廣告需要定時更新,我們可以通過動態(tài)url來達到實時更新緩存內(nèi)容的目的,至于更新的頻率,就看怎么拼接url了。
按天更新:如果是按日期來更新廣告,可以在圖片、視頻的url后面加上“年月日”,這樣的話,就保證了url每日一變,而緩存框架只會在當天第一次加載時拉取數(shù)據(jù),后面就直接從本地緩存加載數(shù)據(jù)了。而之前緩存的內(nèi)容則會被自動清理掉。
按時段更新:如果是按照一天當中的不同時段來更換播放的廣告,則應該先從服務(wù)器拉取有什么時段,然后根據(jù)當前時間處于那個時段之間,在url后拼接 時段的開始或結(jié)束時間 即可。
按日期區(qū)間更新:如果是按照日期跨度來更新,比如說2017/01/01~2017/02/03號播放某幾個視頻。其實這只不過是大概念的時段播放而已,同理,我們先從服務(wù)器查詢出當前日期處于哪些視頻的播放時段之間,然后在url后拼接 起始或終止日期 即可。
按日期+時段更新:綜合上面的日期區(qū)間、一天當中的時間區(qū)間來播放不同廣告:拼接 終止日期+時段的終止時間 即可。
實時更新:如果要保證每次播放都是新的,可以拼接隨機數(shù)。