TT#37311 Extract playable voicemail audio file

What has been done:
- TT#37311, Extract playable voicemail audio file
- TT#37315, Ensure mobile file browser compatibility
- TT#37312, Play audio method
- TT#37379, Implement method for pausing audio
- Fixed issue: DOMException: The play() request was interrupted

Change-Id: I08bafe3cac5cbee7f9ca9888d198f10b813549ec
changes/89/21489/10
raxelsen 7 years ago committed by Hans-Peter Herzog
parent f81efe9610
commit 7abe8f2d44

@ -5,10 +5,10 @@ import _ from 'lodash'
import crypto from 'crypto-browserify'
import { getJsonBody } from './utils'
export function getConversations(options) {
let params = { subscriber_id: options.id, page: options.page, rows: options.rows,
order_by: 'timestamp', order_by_direction: 'desc' };
export function getConversations(id, page, rows) {
return new Promise((resolve, reject) => {
let params = { subscriber_id: id, page: page, rows: rows,
order_by: 'timestamp', order_by_direction: 'desc' };
Vue.http.get('api/conversations/', { params: params })
.then(result => {
let jsonBody = getJsonBody(result.body);
@ -30,7 +30,7 @@ export function getConversations(options) {
else {
reject(new Error('No items returned for this page.'))
}
}).catch(err => {
}).catch((err) => {
reject(err);
});
});
@ -39,10 +39,10 @@ export function getConversations(options) {
export function downloadVoiceMail(id) {
return new Promise((resolve, reject)=>{
Vue.http.get('api/voicemailrecordings/' + id, { responseType: 'blob' })
.then(res => {
.then((res) => {
return res.blob();
}).then(voicemail => {
saveAs(voicemail, "voicemail-" + id + '.wav');
saveAs((voicemail), "voicemail-" + id + '.wav');
resolve();
}).catch((err)=>{
reject(err);
@ -53,13 +53,25 @@ export function downloadVoiceMail(id) {
export function downloadFax(id) {
return new Promise((resolve, reject)=>{
Vue.http.get('api/faxrecordings/' + id, { responseType: 'blob' })
.then(res => {
.then((res) => {
return res.blob();
}).then(fax => {
saveAs(fax, "fax-" + id + '.tif');
saveAs((fax), "fax-" + id + '.tif');
resolve();
}).catch((err)=>{
reject(err);
});
});
}
export function playVoiceMail(options) {
return new Promise((resolve, reject)=>{
let params = { format: options.format };
Vue.http.get(`api/voicemailrecordings/${options.id}`, { params: params, responseType: 'blob' })
.then((res) => {
resolve(URL.createObjectURL(res.body));
}).catch((err)=>{
reject(err);
});
});
}

@ -35,8 +35,8 @@
</ul>
</div>
<div v-if="!isType('fax')" slot="footer">
<!-- <q-card-separator />
<csc-voicemail-player id="csc-voicemail-player" v-if="isType('voicemail')" :id="conversation.id" /> -->
<q-card-separator />
<csc-voicemail-player id="csc-voicemail-player" v-if="isType('voicemail')" :id="conversation.id" />
<q-card-separator />
<q-card-actions align="center">
<q-btn flat round small color="primary" icon="call">

@ -1,26 +1,38 @@
<template>
<div class="voicemail-player">
<audio :src="soundFileUrl" ref="voiceMailSound" preload="none" />
<div class="control-btns">
<q-btn class="play-pause-btn" round flat small color="primary" :icon="playPauseIcon"></q-btn>
<q-btn class="stop-btn" round flat small color="primary" icon="stop"></q-btn>
<q-btn class="play-pause-btn" round flat small color="primary"
:icon="playPauseIcon" @click="toggle()" />
<q-btn class="stop-btn" round flat small color="primary" icon="stop" />
</div>
<q-progress
class="progress-bar"
:percentage="progress"
stripe
animate
color="primary"
/>
<q-progress class="progress-bar" :indeterminate="isLoading" stripe animate color="primary"/>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import { QProgress, QBtn } from 'quasar-framework'
export default {
name: 'csc-voicemail-player',
props: {
id: Number
},
mounted() {
this.$refs.voiceMailSound.addEventListener('play', ()=>{
this.playing = true;
});
this.$refs.voiceMailSound.addEventListener('playing', ()=>{
this.playing = true;
});
this.$refs.voiceMailSound.addEventListener('ended', ()=>{
this.playing = false;
});
this.$refs.voiceMailSound.addEventListener('canplay', ()=>{
this.$refs.voiceMailSound.play();
});
},
components: {
QProgress,
QBtn
@ -28,12 +40,57 @@
data () {
return {
progress: 77,
isPlaying: false
platform: this.$q.platform.is,
voicemail: null,
playing: false
}
},
computed: {
playPauseIcon() {
return this.isPlaying ? 'pause': 'play_arrow';
return this.playing ? 'pause': 'play_arrow';
},
soundFileFormat() {
return this.platform.mozilla ? 'ogg' : 'mp3';
},
soundFileUrl() {
let getter = this.playVoiceMailUrl;
return getter(this.id);
},
isLoading() {
let getter = this.playVoiceMailState;
//console.log(getter(this.id));
return getter(this.id) === 'requesting';
},
...mapGetters('conversations', [
'playVoiceMailState',
'playVoiceMailUrl'
]),
},
methods: {
play() {
this.$refs.voiceMailSound.play();
this.playing = true;
},
pause() {
this.$refs.voiceMailSound.pause();
this.playing = false;
},
load() {
this.$store.dispatch('conversations/playVoiceMail', {
id: this.id,
format: this.soundFileFormat
});
},
toggle() {
if(this.playVoiceMailState(this.id) !== 'succeeded') {
this.load();
}
else if (this.$refs.voiceMailSound.paused) {
this.play();
}
else {
this.pause();
}
}
}
}
@ -56,7 +113,7 @@
display flex
justify-content space-between
.progress-bar
margin-left 16px
margin-left 16px
margin-right 16px
</style>

@ -1,11 +1,13 @@
'use strict';
import Vue from 'vue'
import _ from 'lodash';
import { i18n } from '../i18n';
import {
getConversations,
downloadVoiceMail,
downloadFax
downloadFax,
playVoiceMail
} from '../api/conversations'
const RequestState = {
@ -32,7 +34,10 @@ export default {
downloadFaxState: RequestState.button,
downloadFaxError: null,
reloadConversationsState: RequestState.button,
reloadConversationsError: null
reloadConversationsError: null,
playVoiceMailUrls: {},
playVoiceMailStates: {},
playVoiceMailErrors: {}
},
getters: {
getSubscriberId(state, getters, rootState, rootGetters) {
@ -44,6 +49,16 @@ export default {
reloadConversationsError(state) {
return state.reloadConversationsError ||
i18n.t('pages.conversations.reloadConversationsErrorMessage');
},
playVoiceMailState(state) {
return (id) => {
return state.playVoiceMailStates[id];
}
},
playVoiceMailUrl(state) {
return (id) => {
return state.playVoiceMailUrls[id];
}
}
},
mutations: {
@ -93,6 +108,20 @@ export default {
reloadConversations(state, result) {
state.conversations = result;
state.page++;
},
playVoiceMailRequesting(state, id) {
Vue.set(state.playVoiceMailStates, id, RequestState.requesting);
Vue.set(state.playVoiceMailErrors, id, null);
},
playVoiceMailSucceeded(state, options) {
Vue.set(state.playVoiceMailUrls, options.id, options.url);
Vue.set(state.playVoiceMailStates, options.id, RequestState.succeeded);
Vue.set(state.playVoiceMailErrors, options.id, null);
},
playVoiceMailFailed(state, id, err) {
Vue.set(state.playVoiceMailUrls, id, null);
Vue.set(state.playVoiceMailStates, id, RequestState.failed);
Vue.set(state.playVoiceMailErrors, id, err);
}
},
actions: {
@ -148,6 +177,17 @@ export default {
}).catch((err)=>{
context.commit('downloadFaxFailed', err.body.message);
});
},
playVoiceMail(context, options) {
context.commit('playVoiceMailRequesting', options.id);
playVoiceMail(options).then((url)=>{
context.commit('playVoiceMailSucceeded', {
id: options.id,
url: url
});
}).catch((err)=>{
context.commit('playVoiceMailFailed', options.id, err.mesage);
});
}
}
};

Loading…
Cancel
Save