需要相关说明的,请参考前文
关键代码:
<ion-view class="audio" cache-view="false">
<ion-header-bar class="bar-stable">
<button ng-click="back()">
<i class="ion-arrow-left-c">i> Back
button>
<h1 class="title">音频播放h1>
ion-header-bar>
<ion-content scroll="false" class="no-scroll-bar" overflow-scroll="true" data-tap-disable="true"
scrollbar-y="false" has-bouncing="false">
<div class="animate-zone center-center">
<div class="animate-zone-inner" ng-class="{cur:renderData.playAnimation}">
<span class="center-center">musicspan>
div>
div>
ion-content>
<div class="audio-bottom">
<mp3-container x-source="renderData.source">mp3-container>
div>
ion-view>
css3代码作为参考:
.animate-zone-inner {
position: absolute;
top: 12px;
left: 12px;
right: 12px;
bottom: 12px;
border-radius: 50%;
font-size: 30px;
background-color: #fdfdfd;
color: #808080;
animation: audioRotate 5s linear infinite;
-webkit-animation: audioRotate 5s linear infinite;
animation-play-state: paused;
-webkit-animation-play-state: paused;
}
.animate-zone-inner.cur {
animation-play-state: running;
-webkit-animation-play-state: running;
}
@keyframes audioRotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
@-webkit-keyframes audioRotate {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(360deg);
}
}
关键代码:
.controller('Mp3Ctrl', [
'$scope',
'$sce',
'appUtils',
function($scope, $sce, appUtils) {
$scope.back = appUtils.back;
var renderData = $scope.renderData = {};
renderData.source = $sce.trustAsResourceUrl('audio/music.mp3');
// 接收广播事件
$scope.$on('audio:playState', function(event, data) {
renderData.playAnimation = data;
});
}
]);
关键代码:
<div class="mp3-wrap">
<audio preload="metadata" ng-src="{{source}}">audio>
<div class="audio-controll-bar">
<div class="play-btn center-center" ng-class="{cur:audioData.playing}" on-tap="play()">
<span class="playing-btn">span>
div>
<div class="audio-time clearfix">
<span class="now-time pull-left">{{audioData.current ? audioData.current : '00:00:00'}}span>
<span class="total-time pull-right">{{audioData.duration ? audioData.duration : '00:00:00'}}span>
div>
<div class="audio-progress-zone range">
<div class="audio-range-track center-center">div>
<input class="audio-range-input center-center" type="range" value="0" min="0"
max="{{audioData.durationOrigin}}" ng-model="audioData.currentOrigin" ng-change="seeking()">
div>
div>
div>
关键代码:
.directive('mp3Container', function($timeout, appUtils) {
return {
restrict: 'EA',
templateUrl: 'components/directives/html/mp3.html',
scope: {
source: '='
},
link: function(scope, element) {
// 初始化变量和数据成员
var audio = element.find('audio')[0]; // 获取视频元素
var audioData = scope.audioData = {};
audioData.playing = false; // 控制是否播放中
audioData.currentOrigin = 0; // 当前播放进度
/* 播放与暂停 */
scope.play = function() {
if (!audioData.playing) {
audio.autoplay = audioData.playing = true;
audio.play();
scope.$emit('audio:playState', true); // 发送广播
} else {
audio.autoplay = audioData.playing = false;
audio.pause();
scope.$emit('audio:playState', false); // 发送广播
}
};
// 滑动功能实现
scope.seeking = function() {
audio.currentTime = audioData.currentOrigin;
};
// 事件监听: loadstart
ionic.EventController.on('loadstart', function() {}, audio);
// 事件监听: 元数据加载完成后 此时获取时长
ionic.EventController.on('loadedmetadata', function() {
appUtils.checkToGetMediaDuration(scope, audio, audioData);
this.autoplay = audioData.playing = false; // 为了兼容
scope.$apply();
}, audio);
// 事件监听: durationchange
ionic.EventController.on('durationchange', function() {
appUtils.checkToGetMediaDuration(scope, audio, audioData);
this.autoplay = true; // 为了兼容
scope.$apply();
}, audio);
// 事件监听: onprogress 正在下载中
ionic.EventController.on('progress', function() {
appUtils.checkToGetMediaDuration(scope, audio, audioData);
scope.$apply();
}, audio);
// 事件监听: waiting
ionic.EventController.on('waiting', function() {
this.autoplay = audioData.playing = false;
scope.$apply();
}, audio);
// 事件监听: seeking
ionic.EventController.on('seeking', function() {
audioData.playing = this.autoplay = false; // 为了兼容 = true ; 无法继续播放时loading ; seeking 保持播放状态
scope.$emit('audio:playState', false); // 发送广播
$timeout(function() {
audio.play(); // 强制播放
scope.$emit('audio:playState', true); // 发送广播
});
scope.$apply();
}, audio);
// 事件监听: 在可播放时 只会触发一次 , 播放按钮状态 : 可播放
ionic.EventController.on('playing', function() {
appUtils.checkToGetMediaDuration(scope, audio, audioData);
this.autoplay = audioData.playing = true; // 为了兼容 此处 loading 应为false,但安卓低端机器存在问题
scope.$emit('audio:playState', true); // 发送广播
scope.$apply();
}, audio);
// 事件监听: 监听暂停事件
ionic.EventController.on('pause', function() {
audioData.playing = false;
scope.$apply();
}, audio);
// 事件监听: 音频播放位置发生改变时触发
ionic.EventController.on('timeupdate', function() {
appUtils.checkToGetMediaDuration(scope, audio, audioData);
audioData.currentOrigin = audio.currentTime; // 获取视频当前时间
audioData.current = appUtils.handlePlayingTime(audio.currentTime); // 获取格式转换之后的视频当前时间
scope.$apply();
}, audio);
// 事件监听: 视频可以流畅播放到结束
ionic.EventController.on('canplaythrough', function() {}, audio);
// 事件监听: 视频可以流畅播放
ionic.EventController.on('canplay', function() {}, audio);
// 事件监听: 播放完成
ionic.EventController.on('ended', function() {
this.pause();
scope.$emit('audio:playState', false); // 发送广播
scope.$apply();
}, audio);
}
};
});