2012-07-16 15 views
8

से फिर से शुरू होता है मैं अक्सर पढ़ता हूं कि Web Audio API के साथ ऑडियो फ़ाइलों को रोकना/फिर से शुरू करना संभव नहीं है।
लेकिन अब मैंने example देखा जहां उन्होंने वास्तव में इसे रोकना और फिर से शुरू करना संभव बना दिया। मैंने यह पता लगाने की कोशिश की कि उन्होंने यह कैसे किया। मैंने सोचा कि शायद source.looping = false कुंजी है, लेकिन यह नहीं था।
अब के लिए मेरा ऑडियो हमेशा शुरुआत से फिर से खेल रहा है।वेब ऑडियो एपीआई विराम

यह मेरे वर्तमान कोड

var context = new (window.AudioContext || window.webkitAudioContext)(); 

function AudioPlayer() { 
    this.source = context.createBufferSource(); 
    this.analyser = context.createAnalyser(); 
    this.stopped = true; 
} 

AudioPlayer.prototype.setBuffer = function(buffer) { 
    this.source.buffer = buffer; 
    this.source.looping = false; 
}; 

AudioPlayer.prototype.play = function() { 
    this.source.connect(this.analyser); 
    this.analyser.connect(context.destination); 

    this.source.noteOn(0); 
    this.stopped = false; 
}; 

AudioPlayer.prototype.stop = function() { 
    this.analyser.disconnect(); 
    this.source.disconnect(); 
    this.stopped = true; 
}; 

किसी को क्या करना है पता है, यह काम करने के लिए है?

उत्तर

5

किसी भी समय अपने उदाहरण के स्रोत की जाँच के खर्च के बिना, मैं कहेंगे आप (https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html#methodsandparams-AudioBufferSourceNode)

बस आप कितनी दूर बफर में थे का ट्रैक रखने AudioBufferSourceNode की noteGrainOn विधि का उपयोग करना चाहते हैं जब आपने नोटऑफ को बुलाया, और उसके बाद नोट करें जब एक नया ऑडियोबफर सॉर्स नोड पर फिर से शुरू होता है।

क्या यह समझ में आया?

संपादित करें: अद्यतन API कॉल के लिए नीचे दी गई टिप्पणियां देखें।

+0

वैसे वह उदाहरण में 'noteGrainOn()' का उपयोग नहीं करता है (हालांकि यह पता नहीं लगा सकता कि वह ऐसा कैसे करता है)। लेकिन वैसे भी, यह एक आकर्षण की तरह काम करता है, इसलिए मैं इसे एक स्वीकार्य उत्तर के रूप में ले जाऊंगा। धन्यवाद :) –

+1

नोटग्रेनऑन() अब spec में बदल दिया गया है, जैसा कि नोट है() - दोनों अब अनाज ऑफसेट तर्क के साथ या बिना खेल रहे हैं। हालांकि, यह अभी तक समर्थित नहीं देखा है। – LeeGee

+1

यह वास्तव में 'स्टार्ट' (तर्क के साथ या बिना 'शुरू होता है (कैसे सूनडइनबफर, अवधि के लिए) कैसे और यह क्रोम कैनरी –

15

ओस्कर का उत्तर और ऐके की टिप्पणी बहुत उपयोगी है, लेकिन मुझे एक कोड उदाहरण याद आ रहा था। तो मैंने एक लिखा: http://jsfiddle.net/v3syS/2/ मुझे उम्मीद है कि यह मदद करता है।

var url = 'http://thelab.thingsinjars.com/web-audio-tutorial/hello.mp3'; 

var ctx = new webkitAudioContext(); 
var buffer; 
var sourceNode; 

var startedAt; 
var pausedAt; 
var paused; 

function load(url) { 
    var request = new XMLHttpRequest(); 
    request.open('GET', url, true); 
    request.responseType = 'arraybuffer'; 
    request.onload = function() { 
     ctx.decodeAudioData(request.response, onBufferLoad, onBufferError); 
    }; 
    request.send(); 
}; 

function play() { 
    sourceNode = ctx.createBufferSource(); 
    sourceNode.connect(ctx.destination); 
    sourceNode.buffer = buffer; 
    paused = false; 

    if (pausedAt) { 
     startedAt = Date.now() - pausedAt; 
     sourceNode.start(0, pausedAt/1000); 
    } 
    else { 
     startedAt = Date.now(); 
     sourceNode.start(0); 
    } 
}; 

function stop() { 
    sourceNode.stop(0); 
    pausedAt = Date.now() - startedAt; 
    paused = true; 
}; 

function onBufferLoad(b) { 
    buffer = b; 
    play(); 
}; 

function onBufferError(e) { 
    console.log('onBufferError', e); 
}; 

document.getElementById("toggle").onclick = function() { 
    if (paused) play(); 
    else stop(); 
}; 

load(url); 
0

वेबऑडियो एपीआई में अंतर्निहित विराम कार्यक्षमता की कमी मुझे एक बड़ी निगरानी की तरह लगती है। संभवतः, भविष्य में योजनाबद्ध MediaElementSource का उपयोग करके ऐसा करना संभव होगा, जो आपको वेब ऑडियो पर एक तत्व (जो रोकना बंद करता है) को हुक करने देगा। अभी के लिए, अधिकांश वर्कअराउंड प्लेबैक समय को याद रखने पर आधारित होते हैं (जैसे कि इम्ब्रिज़ी के उत्तर में वर्णित)। ऐसे कामकाज में समस्याएं होती हैं जब लूपिंग ध्वनि (कार्यान्वयन लूप अंतराल या नहीं?), और जब आप प्लेबैक गतिशील रूप से ध्वनि की गति को बदलने की अनुमति देते हैं (जैसे दोनों समय को प्रभावित करते हैं)। एक और, समान रूप से हैक-ish और तकनीकी रूप से गलत है, लेकिन बहुत सरल समाधान का आप उपयोग कर सकते हैं:

source.playbackRate = paused?0.0000001:1; 

दुर्भाग्य से, 0 playbackRate लिए एक मान्य मान (जो वास्तव में ध्वनि को थामने होगा) नहीं है। हालांकि, कई व्यावहारिक उद्देश्यों के लिए, 0.000001 की तरह कुछ बहुत कम मूल्य पर्याप्त है, और यह किसी भी श्रव्य आउटपुट का उत्पादन नहीं करेगा।

+0

+10 एक त्वरित हैक के लिए :-) – Sam

+0

यह एक अच्छा विचार नहीं है, क्योंकि आप ब्राउज़र को किसी भी अप्रयुक्त ऑडियो बफर को साफ करने से रोक देंगे। यह एपीआई के साथ काम करने के लिए थोड़ा सा गुंजाइश है, लेकिन यह प्रदर्शन और स्मृति दक्षता के कारणों के लिए इस तरह से डिजाइन किया गया है। ओपीएस प्रश्न में एक छोटी रैपर लाइब्रेरी एक बेहतर दृष्टिकोण है। –

0

अद्यतन: यह केवल क्रोम के लिए मान्य है। फ़ायरफ़ॉक्स (v29) अभी तक MediaElementAudioSourceNode.mediaElement संपत्ति को लागू नहीं करता है।

यह मानते हुए कि आप पहले से ही AudioContext संदर्भ और अपने मीडिया स्रोत (जैसे के माध्यम से AudioContext.createMediaElementSource() विधि कॉल) है, तो आप अपने स्रोत है, उदा पर MediaElement.play() और MediaElement.pause() कॉल कर सकते हैं

source.mediaElement.pause(); 
source.mediaElement.play(); 

हैक्स और कामकाज की कोई ज़रूरत नहीं है, यह समर्थित है। यदि आप अपने स्रोत के रूप में <audio> टैग के साथ काम कर रहे हैं, तो आपको अपनी जावास्क्रिप्ट में ऑडियो तत्व पर सीधे रोकना नहीं चाहिए, जो प्लेबैक को रोक देगा।

9

मौजूदा ब्राउज़र में (क्रोम 43, फ़ायरफ़ॉक्स 40) देखते हैं अब 'निलंबित' और 'फिर से शुरू' AudioContext के लिए उपलब्ध तरीके:

var audioCtx = new AudioContext(); 
susresBtn.onclick = function() { 
    if(audioCtx.state === 'running') { 
    audioCtx.suspend().then(function() { 
     susresBtn.textContent = 'Resume context'; 
    }); 
    } else if(audioCtx.state === 'suspended') { 
    audioCtx.resume().then(function() { 
     susresBtn.textContent = 'Suspend context'; 
    }); 
    } 
} 

(https://developer.mozilla.org/en-US/docs/Web/API/AudioContext/suspend से संशोधित उदाहरण कोड)

3

वास्तव में वेब -ऑडियो एपीआई आपके लिए विराम और प्ले कार्य कर सकता है। यह ऑडियो संदर्भ की वर्तमान स्थिति (चल रहे हैं या निलंबित) जानता है, इसलिए आप इस आसान तरीका में यह कर सकते हैं:

susresBtn.onclick = function() { 
 
    if(audioCtx.state === 'running') { 
 
    audioCtx.suspend() 
 
    } else if(audioCtx.state === 'suspended') { 
 
    audioCtx.resume() 
 
    } 
 
}

मुझे आशा है कि यह कर सकते हैं।

0

2017 में, ctx.currentTime का उपयोग करके गीत में बिंदु को ट्रैक रखने के लिए अच्छी तरह से काम करता है। नीचे दिया गया कोड एक बटन (गीत स्टार्टपोज) का उपयोग करता है जो एक प्ले & पॉज़ बटन के बीच टॉगल करता है। मैंने सादगी के लिए वैश्विक चर का उपयोग किया। परिवर्तनीय संगीतस्टार्टपॉइंट ट्रैक करता है कि आप गीत में किस समय हैं। संगीत एपी सेकंड में समय का ट्रैक रखता है।

0 (गीत की शुरुआत)

var ctx = new webkitAudioContext(); 
var buff, src; 
var musicLoaded = false; 
var musicStartPoint = 0; 
var songOnTime, songEndTime; 
var songOn = false; 

songStartPause.onclick = function() { 

    if(!songOn) { 
    if(!musicLoaded) { 
     loadAndPlay(); 
     musicLoaded = true; 
    } else { 
     play(); 
    } 

    songOn = true; 
    songStartPause.innerHTML = "||" //a fancy Pause symbol 

    } else { 
    songOn = false; 
    src.stop(); 
    setPausePoint(); 
    songStartPause.innerHTML = ">" //a fancy Play symbol 
    } 
} 

उपयोग ctx.currentTime पर अपने प्रारंभिक musicStartPoint सेट हालांकि अब तक के लिए तुम थे समय गीत से जब यह शुरू कर दिया समाप्त होता घटाना, और संलग्न इस समयावधि को शुरुआत में गीत में।

function setPausePoint() { 
    songEndTime = ctx.currentTime; 
    musicStartPoint += (songEndTime - songOnTime); 
} 

लोड/प्ले फ़ंक्शन।

function loadAndPlay() { 
    var req = new XMLHttpRequest(); 
    req.open("GET", "//mymusic.com/unity.mp3") 
    req.responseType = "arraybuffer"; 
    req.onload = function() { 
    ctx.decodeAudioData(req.response, function(buffer) { 
     buff = buffer; 
     play(); 
    }) 
    } 
    req.send(); 
} 

function createBuffer() { 
     src = ctx.createBufferSource(); 
     src.buffer = buff; 
    } 


function connectNodes() { 
    src.connect(ctx.destination); 
} 

अन्त में, नाटक समारोह गीत बताता है निर्दिष्ट musicStartPoint पर शुरू करने के लिए (और इसे तुरंत खेलने के लिए), और भी songOnTime चर सेट।

function play(){ 
    createBuffer() 
    connectNodes(); 
    songOnTime = ctx.currentTime; 
    src.start(0, musicStartPoint); 
} 

* Sidenote: मैं जानता हूँ कि यह क्लिक समारोह में songOnTime सेट करने के लिए क्लीनर लग सकता है, लेकिन मैं समझ यह समझ में आता है वैसे ही जैसे हम कैसे हड़पने, संभव के रूप में src.start के रूप में पास बार कोड हड़पने के लिए src.stop के लिए जितना संभव हो सके विराम का समय।

संबंधित मुद्दे