web-dev-qa-db-ja.com

関数によってaudio.duration値を取得する方法

オーディオプレーヤーの場合、オーディオトラックの継続時間を取得する必要があります。オーディオのsrcを取得し、その継続時間を返す関数が必要です。これが私がやろうとしていることですが、うまくいきません:

function getDuration(src){
    var audio = new Audio();
    audio.src = "./audio/2.mp3";
    var due;
    return getVal(audio);
}
function getVal(audio){
    $(audio).on("loadedmetadata", function(){
        var val = audio.duration;
        console.log(">>>" + val);
        return val;
    });
}

2つの関数に分割しようとしましたが、機能しません。それが仕事の機能のようだったらそれは素晴らしいでしょう。

何か案が?

11
TheGuy

イベントの発生に依存しているため、getDurationまたはgetValで値を返すことはできません

代わりに、次のようなコールバック関数を使用したい(コールバック)

例では、このように書かれたスパンに期間を入れたいと仮定します

<span id="duration"></span>

function getDuration(src, cb) {
    var audio = new Audio();
    $(audio).on("loadedmetadata", function(){
        cb(audio.duration);
    });
    audio.src = src;
}
getDuration("./audio/2.mp3", function(length) {
    console.log('I got length ' + length);
    document.getElementById("duration").textContent = length;
});

長さを「知る」必要があるすべてのコードは、コールバック関数の内部にある必要があります(console.logがある場所)


promiseの使用

function getDuration(src) {
    return new Promise(function(resolve) {
        var audio = new Audio();
        $(audio).on("loadedmetadata", function(){
            resolve(audio.duration);
        });
        audio.src = src;
    });
}
getDuration("./audio/2.mp3")
.then(function(length) {
    console.log('I got length ' + length);
    document.getElementById("duration").textContent = length;
});

イベントの使用-注意'myAudioDurationEvent'は明らかに(ほぼ)何でもかまいません

function getDuration(src, obj) {
    return new Promise(function(resolve) {
        var audio = new Audio();
        $(audio).on("loadedmetadata", function(){
            var event = new CustomEvent("myAudioDurationEvent", {
                detail: {
                    duration: audio.duration,

                }
            });
            obj.dispatchEvent(event);
        });
        audio.src = src;
    });
}
var span = document.getElementById('xyz'); // you'll need to provide better logic here
span.addEventListener('myAudioDurationEvent', function(e) {
    span.textContent = e.detail.duration;
});
getDuration("./audio/2.mp3", span);

ただし、これらのソリューションでも、変更されたgetDuration関数に宛先を渡すことで、コールバックまたはpromiseを使用してこれを同様に行うことができます。たとえば、1つのスパンが継続時間で複数回更新された場合、イベントリスナーの使用に関する私の方が適切でした-このソリューションそれでも各スパンは1回だけなので、他の方法でも簡単に達成できます。


この回答のコメントの新しい情報を考えると、これはより良い解決策だと思います

function getDuration(src, destination) {
    var audio = new Audio();
    $(audio).on("loadedmetadata", function(){
        destination.textContent = audio.duration;
    });
    audio.src = src;
}

そして、このように必要に応じてgetDurationを呼び出します

var span = createOrGetSomeSpanElement();
getDuration("./audio/2.mp3", span);

createOrGetSomeSpanElementgetDuration関数で使用する宛先要素を返します-これをどのように行うかはあなた次第です。ループでプレイリストを作成するときに、いくつかの要素が作成されていると思いますすでに作成された音声の長さを受け取るために-時々半分尋ねられた質問に答えることは困難です

13
Jaromanda X