Как воспроизвести звук с помощью скрипта GreaseMonkey в FireFox при ошибке политики безопасности содержимого?

var audioPlayer = new Audio("http://URLTOMYSOUND/ping.mp3");
audioPlayer.play();

Я получаю эту ошибку при загрузке аудио:

Политика безопасности контента: Настройки страницы заблокировали загрузку ресурса на...

Как мне обойти это? Мне все равно, где звук, я просто хочу его воспроизвести. Это может быть локально, но у меня сложилось впечатление, что локальный доступ к файлам также будет запрещен.


person Almo    schedule 17.02.2015    source источник


Ответы (1)


Невозможно (на данный момент) воспроизводить звук из файла, если вы столкнулись с проблемами политики безопасности контента (CSP) начиная с Greasemonkey 2.3. Если вы можете изменить заголовки HTTP сайта, на котором хотите работать, это возможно. См. Использование политики безопасности контента и директивы политики CSP.

Использование GM_xmlhttpRequest, которое "позволяет этим запросам пересекать одни и те же границы политики происхождения", не работает из-за ошибки. в текущей GM 2.3. См. выпуск № 2045. Проблема связана с невозможностью скопировать ArrayBuffer в землю песочницы, чтобы получить надлежащие разрешения для декодирования и т. д.

Фрагмент ниже должен работать в будущих версиях GM.

// ==UserScript==
// @name        Testing Web Audio: Load from file
// @namespace   http://ericeastwood.com/
// @include     http://example.com/
// @version     1
// @grant       GM_xmlhttpRequest
// ==/UserScript==
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var context = new AudioContext();
// Note: this is not an actual reference to a real mp3
var url = 'http://example.com/some.mp3';

var soundLoadedPromise = new Promise(function(resolve, reject) {
    // This will get around the CORS issue
    //      http://wiki.greasespot.net/GM_xmlhttpRequest
    var req = GM_xmlhttpRequest({
        method: "GET",
        url: url,
        responseType: 'arraybuffer',
        onload: function(response) {
            try {
                context.decodeAudioData(response.response, function(buffer) { 
                    resolve(buffer)
                }, function(e) {
                    reject(e);
                }); 
            }
            catch(e) {
                reject(e);
            }
        }
    });
});

soundLoadedPromise.then(function(buffer) {
    playSound(buffer);
}, function(e) {
    console.log(e);
});

function playSound(buffer) {
    // creates a sound source
    var source = context.createBufferSource();
    // tell the source which sound to play
    source.buffer = buffer;
    // connect the source to the context's destination (the speakers)
    source.connect(context.destination);
    // play the source now
    // note: on older systems, may have to use deprecated noteOn(time);
    source.start(0);
}

На данный момент, если вам нужен только какой-то звук, я бы просто процедурно сгенерировал его с помощью осциллятора. В приведенной ниже демонстрации используется AudioContext.createOscillator.

Демонстрация: jsFiddle

// ==UserScript==
// @name        Test Web Audio: Oscillator - Web Audio
// @namespace   http://ericeastwood.com/
// @include     http://example.com/
// @version     1
// @grant       none
// ==/UserScript==
window.AudioContext = window.AudioContext || window.webkitAudioContext;

context = new AudioContext();

var o = context.createOscillator();
o.type = 'sine';
o.frequency.value = 261.63;
o.connect(context.destination);

// Start the sound
o.start(0);
// Play the sound for a second before stopping it
setTimeout(function() {
    o.stop(0);
}, 1000);
person MLM    schedule 17.02.2015
comment
Трудно сказать, работает этот пример или нет, поскольку Greasemonkey обновил свой API. Например, функция теперь называется GM.xmlhttpRequest. - person jadelord; 06.03.2018