"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Functional_1 = require("../../../../../../Class/Functional");
const MediaStream_1 = require("../../../../../../wrap/MediaStream");
const _ids_1 = require("../../../../../_ids");
async function createMediaStreamFromUrl(src) {
    // @ts-ignore
    const audioContext = new (window.AudioContext || window.webkitAudioContext)();
    let source;
    try {
        const response = await fetch(src);
        const arrayBuffer = await response.arrayBuffer();
        const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
        source = audioContext.createBufferSource();
        source.buffer = audioBuffer;
        const mediaStreamDestination = audioContext.createMediaStreamDestination();
        source.connect(mediaStreamDestination);
        source.start();
        const stream = mediaStreamDestination.stream;
        return { stream, source };
    }
    catch (error) {
        if (source) {
            source.stop();
            source.disconnect();
        }
        throw new Error('could not load media stream');
    }
}
class AudioSource extends Functional_1.Functional {
    constructor(system) {
        super({
            i: ['src'],
            o: ['stream'],
        }, {
            output: {
                stream: {
                    ref: true,
                },
            },
        }, system, _ids_1.ID_AUDIO_SOURCE);
        const { api: { window: { Audio }, }, } = this.__system;
        this.addListener('play', () => {
            if (this._source) {
                this._source.start();
            }
        });
        this.addListener('pause', () => {
            if (this._source) {
                this._source.stop();
            }
        });
    }
    async f({ src }, done) {
        let srcObject;
        let source;
        try {
            ;
            ({ stream: srcObject, source } = await createMediaStreamFromUrl(src));
        }
        catch (err) {
            done(undefined, err.message);
            return;
        }
        this._source = source;
        const stream = (0, MediaStream_1.wrapMediaStream)(srcObject, this.__system);
        done({
            stream,
        });
    }
    d() {
        if (this._source) {
            this._source.stop();
            this._source.disconnect();
            this._source = undefined;
        }
    }
}
exports.default = AudioSource;
//# sourceMappingURL=index.js.map