Ionic2 播放mp3功能实现
在开发app的过程中有需要播放mp3的功能,一直想实现,但苦于具体的困难一直未能实现,经过一段时间的资料查询和测试,最终摸索出来,现记录如下:
1.最重要的是安装第三方插件ionic-audio,开源地址是 https://github.com/arielfaur/ionic-audio
第一,cd D:\Dev\sourcecode\IonicApp\FlexApp\IonicEnglish 目录下
第二,安装插件到本地: npm install ionic-audio --save, 安装完成后的效果图如下
2.在src/app/app.module.ts文件中加入 IonicAudioModule.forRoot(),如图
3.在我们自己的页面中引入AudioProvider类
1 import { Component } from '@angular/core'; 2 import { NavController, NavParams,LoadingController } from 'ionic-angular'; 3 import { URLSearchParams } from '@angular/http'; 4 import { CommonService } from '../../providers/baseService/CommonService'; 5 import { AudioProvider } from 'ionic-audio'; 6 7 /* 8 Generated class for the English page. 9 10 See http://ionicframework.com/docs/v2/components/#navigation for more info on 11 Ionic pages and navigation. 12 */ 13 14 @Component( 15 { 16 selector: 'page-english', 17 templateUrl: 'english.html' 18 }) 19 20 export class EnglishPage 21 { 22 private groupEnglish ; 23 private shownGroup ; 24 public englishWord:string; 25 public loading; 26 27 public startIndex: number; 28 29 constructor(public navCtrl: NavController, public navParams: NavParams,private loadCtrl:LoadingController,private audioProvider: AudioProvider,private service:CommonService) 30 { 31 this.groupEnglish = []; 32 this.shownGroup = {}; 33 this.startIndex = 0; 34 } 35 36 ionViewDidLoad() 37 { 38 console.log('ionViewDidLoad EnglishPage'); 39 } 40 41 search() 42 { 43 let url = 'XXXXX'; 44 let val = this.englishWord; 45 let searchParams = new URLSearchParams() 46 searchParams.set('key', val); 47 48 this.loading = this.loadCtrl.create({ content: '加载中...'}); 49 this.loading.present(); 50 this.service.getJsonDataParameter(url,searchParams).then(result => 51 { 52 //this.groupEnglish = result.Data; 53 this.groupEnglish = []; 54 for(var i = 0; i< result.Data.length; i++) 55 { 56 let ele = { 57 src: 'url'+result.Data[i].Word+'.mp3', 58 item : result.Data[i] 59 }; 60 this.groupEnglish.push(ele); 61 } 62 this.loading.dismiss(); 63 }, 64 err => 65 { 66 67 }); 68 } 69 70 onTrackFinished(track: any) 71 { 72 if(this.audioProvider.tracks.length > this.startIndex ) 73 { 74 this.startIndex = this.startIndex + 1; 75 this.autoPlay(); 76 } 77 else 78 { 79 this.startIndex = 0; 80 this.audioProvider.stop(); 81 } 82 } 83 84 autoPlay() 85 { 86 this.audioProvider.play(this.startIndex); 87 } 88 89 toggleGroup(group,id) 90 { 91 if (this.isGroupShown(group)) 92 { 93 this.shownGroup = null; 94 } 95 else 96 { 97 this.shownGroup = group; 98 this.startIndex = id; 99 this.autoPlay(); 100 } 101 } 102 103 isGroupShown(group) 104 { 105 return this.shownGroup === group; 106 } 107 }
播放mp3的数据格式是A:
{ src: 'mp3数据源,本地的或网络的都可以,必须的字段', artist: '作者名称', title: '标题', art: '图片', preload: 'metadata' // tell the plugin to preload metadata such as duration for this track, set to 'none' to turn off },
我这里就根据自己的需要就只用了src数据源字段,同时添加了自己的一个类字段item .
将获得的数据groupEnglish数组绑定到对应的网页上,
1 <ion-content> 2 3 <ion-list> 4 <audio-track #audio *ngFor="let item of groupEnglish" [track]="item" (onFinish)="onTrackFinished($event)"> 5 <ion-item> 6 <ion-item class="rectangle" (click)="toggleGroup(item.item,audio.id)"> 7 <i class="ion-icon" > 8 {{item.item.Word}} 9 </i> 10 <i style="color:green;font-size:14px"> {{item.item.Accent}}</i> 11 <i style="font-size:10px">词频</i> 12 <i style="color:red;font-size:10px"> {{item.item.Index}}</i> 13 <i style="font-size:10px">{{item.item.Source}}</i> 14 </ion-item > 15 <div *ngIf="isGroupShown(item.item)"> 16 <ion-item text-wrap class="rectangle" *ngFor="let it of item.item.Items" > 17 <div [innerHTML]="it.Sentence"> 18 </div> 19 </ion-item> 20 </div> 21 </ion-item> 22 </audio-track> 23 </ion-list> 24 </ion-content>
其中的audio-track节点是必须的,数据绑定之后的#audio 是一个类,包含了前面的数据源数据A和我们自己的数据item
这里尤其强调的是audio其中的id字段,播放mp3的时候是根据这个id来确定的,这个id基本上是按顺序从0开始的。
基本都这里就实现了mp3的播放。
4.实现自动的播放mp3功能。
基本思路是每一个mp3播放完毕之后都会调用onTrackFinished事件,在这里,调用下一个mp3的开始。
这里一个有意思的事情是,每次查询之后将groupEnglish清零,下标也清零,重新开始从头播放。如果是第一次查询出来的结果,这样一个个的播放是没问题的,但第二次查询出来之后播放的还是第一次的数据,经排查原因是this.audioProvider.tracks还是保留了上一次的数据,所以要么清除上次的数据,要么在原来的基础上id继续增加,我选择的是后者。