ionic中的在线mp3播放功能

前言

需要相关说明的,请参考前文

效果预览

这里写图片描述

github演示地址

Audio模块中的html

关键代码:

<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">music</span>
            </div>
        </div>
    </ion-content>
    <div class="audio-bottom">
        <!-- audio元素 -->
        <mp3-container x-source="renderData.source"></mp3-container>
    </div>
</ion-view>

Audio模块中的播放动画

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);
    }
}

Audio模块中的controller

关键代码:

.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;
            });
        }
    ]);

Audio模块中的指令模板

关键代码:

<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>

Audio模块中的指令逻辑

关键代码:

.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);
                }
            };
        });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值