Safari中HTML5音频音量问题

3

我注意到在Safari中音频播放的音量不是100%,即使我已经将控制设置为“1”。

是否还有其他方法可以做到这一点,或者这可能是脚本问题?

使用以下控件,在Firefox中音频以100%的音量播放。

更新: 显然,我用于音量的控件在Safari中无法识别(请参见下文),因此我现在正在寻找一种在Safari中使用此播放器以100%音量播放音频的方法。

根据Safari开发人员库,读取音量始终返回1,这就是我设置我的播放器的值;但是,在Safari中,音量略低于其他浏览器。

问题可能出现在我的脚本中,还是仅仅是Safari的问题?

另外, 我注意到更改音量参数会使Safari中的音量变小,但1并不等于100%;因此,它确实起到了一些作用,但仍然存在问题。

以下是我的HTML代码:

<head>
<script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
<script src="src/jquery.ubaplayer.js"></script>
<script>
jQuery(document).ready(function() { 
   jQuery.noConflict();
   jQuery(function(){
            jQuery("#ubaPlayer").ubaPlayer({
            codecs: [{name:"MP3", codec: 'audio/mpeg;'}]
            });

    });
    jQuery('a[rel=vidbox]').click(function () {

        if (jQuery("#ubaPlayer").ubaPlayer("playing") === true) {
            jQuery("#ubaPlayer").ubaPlayer("pause");
            }
        return false;
    });
})
</script>
</head>

<body>
<div id="ubaPlayer"></div>
    <ul class="controls">
        <li><a class="audioButton" href="mp3/dontthinktwice.mp3">
        Don't Think Twice (Bob Dylan)</a></li>
        <li><a class="audioButton" href="mp3/livingforthecity.mp3">
        Living for the City (Stevie Wonder)</a></li>
    </ul>
</body>

音频播放器Javascript:

(function($) {
var defaults = {
    audioButtonClass: "audioButton",
    autoPlay: null,
    codecs: [{
        name: "OGG",
        codec: 'audio/ogg; codecs="vorbis"'
    }, {
        name: "MP3",
        codec: 'audio/mpeg'
    }],
    continuous: false,
    extension: null,
    flashAudioPlayerPath: "libs/swf/player.swf",
    flashExtension: ".mp3",
    flashObjectID: "audioPlayer",
    loadingClass: "loading",
    loop: false,
    playerContainer: "player",
    playingClass: "playing",
    swfobjectPath: "libs/swfobject/swfobject.js",
    volume: 1
},
    currentTrack, isPlaying = false,
    isFlash = false,
    audio, $buttons, $tgt, $el, playTrack, resumeTrack, pauseTrack, methods = {
        play: function(element) {
            $tgt = element;
            currentTrack = _methods.getFileNameWithoutExtension($tgt.attr("href"));
            isPlaying = true;
            $tgt.addClass(defaults.loadingClass);
            $buttons.removeClass(defaults.playingClass);

            if (isFlash) {
                if (audio) {
                    _methods.removeListeners(window);
                }
                audio = document.getElementById(defaults.flashObjectID);
                _methods.addListeners(window);
                audio.playFlash(currentTrack + defaults.extension);
            } else {
                if (audio) {
                    audio.pause();
                    _methods.removeListeners(audio);
                }
                audio = new Audio("");
                _methods.addListeners(audio);
                audio.id = "audio";
                audio.loop = defaults.loop ? "loop" : "";
                audio.volume = defaults.volume;
                audio.src = currentTrack + defaults.extension;
                audio.play();
            }
        },

        pause: function() {
            if (isFlash) {
                audio.pauseFlash();
            } else {
                audio.pause();
            }

            $tgt.removeClass(defaults.playingClass);
            isPlaying = false;
        },

        resume: function() {
            if (isFlash) {
                audio.playFlash();
            } else {
                audio.play();
            }
            $tgt.addClass(defaults.playingClass);
            isPlaying = true;
        },

        playing: function() {
            return isPlaying;
        }
    },

    _methods = {
        init: function(options) {
            var types;

            //set defaults
            $.extend(defaults, options);
            $el = this;

            //listen for clicks on the controls
            $(".controls").bind("click", function(event) {
                _methods.updateTrackState(event);
                return false;
            });
            $buttons = $("." + defaults.audioButtonClass);

            types = defaults.codecs;
            for (var i = 0, ilen = types.length; i < ilen; i++) {
                var type = types[i];
                if (_methods.canPlay(type)) {
                    defaults.extension = [".", type.name.toLowerCase()].join("");
                    break;
                }
            }

            if (!defaults.extension || isFlash) {
                isFlash = true;
                defaults.extension = defaults.flashExtension;
            }

            if (isFlash) {
                $el.html("<div id='" + defaults.playerContainer + "'/>");
                $.getScript(defaults.swfobjectPath, function() {
                    swfobject.embedSWF(defaults.flashAudioPlayerPath, defaults.playerContainer, "0", "0", "9.0.0", "swf/expressInstall.swf", false, false, {
                        id: defaults.flashObjectID
                    }, _methods.swfLoaded);
                });
            } else {
                if (defaults.autoPlay) {
                    methods.play(defaults.autoPlay);
                }
            }
        },

        updateTrackState: function(evt) {
            $tgt = $(evt.target);
            if (!$tgt.hasClass("audioButton")) {
                return;
            }
            if (!audio || (audio && currentTrack !== _methods.getFileNameWithoutExtension($tgt.attr("href")))) {
                methods.play($tgt);
            } else if (!isPlaying) {
                methods.resume();
            } else {
                methods.pause();
            }
        },

        addListeners: function(elem) {
            $(elem).bind({
                "canplay": _methods.onLoaded,
                "error": _methods.onError,
                "ended": _methods.onEnded
            });
        },

        removeListeners: function(elem) {
            $(elem).unbind({
                "canplay": _methods.onLoaded,
                "error": _methods.onError,
                "ended": _methods.onEnded
            });
        },

        onLoaded: function() {
            $buttons.removeClass(defaults.loadingClass);
            $tgt.addClass(defaults.playingClass);

            audio.play();
        },

        onError: function() {
            $buttons.removeClass(defaults.loadingClass);
            if (isFlash) {
                _methods.removeListeners(window);
            } else {
                _methods.removeListeners(audio);
            }
        },

        onEnded: function() {
            isPlaying = false;
            $tgt.removeClass(defaults.playingClass);
            currentTrack = "";
            if (isFlash) {
                _methods.removeListeners(window);
            } else {
                _methods.removeListeners(audio);
            }

            if (defaults.continuous) {
                var $next = $tgt.next().length ? $tgt.next() : $(defaults.audioButtonClass).eq(0);
                methods.play($next);
            }

        },

        canPlay: function(type) {
            if (!document.createElement("audio").canPlayType) {
                return false;
            } else {
                return document.createElement("audio").canPlayType(type.codec).match(/maybe|probably/i) ? true : false;
            }
        },

        swfLoaded: function() {
            if (defaults.autoPlay) {
                setTimeout(function() {
                    methods.play(defaults.autoPlay);
                }, 500);
            }
        },

        getFileNameWithoutExtension: function(fileName) {
            //this function take a full file name and returns an extensionless file name
            //ex. entering foo.mp3 returns foo
            //ex. entering foo returns foo (no change)
            var fileNamePieces = fileName.split('.');
            fileNamePieces.pop();
            return fileNamePieces.join(".");
        }
    };

$.fn.ubaPlayer = function(method) {
    if (methods[method]) {
        return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
    } else if (typeof method === "object" || !method) {
        return _methods.init.apply(this, arguments);
    } else {
        $.error("Method " + method + " does not exist on jquery.ubaPlayer");
    }
};})(jQuery);

1
Safari使用WebKit引擎,而Firefox使用Gecko引擎。它们都以不同的方式解释JavaScript。 - ShuklaSannidhya
@Sann - 我注意到更改音量参数会在Safari中减弱音量,但1并不等于100%。因此,它确实有一些效果,但并没有完全控制。 - pianoman
@Sann 不,他们不会。那只是纯粹的错误。不同的是对某些功能和API的支持。 - Oliver Weichhold
很遗憾,我在使用Javascript控制HTML5音频的音量方面找不到太多的文档。 - pianoman
2个回答

4
你是在谈论移动版Safari吗?如果是的话,那么音量根本无法通过Javascript进行设置。
请阅读这篇文章:http://www.ibm.com/developerworks/library/wa-ioshtml5/ 如果你说的是桌面版Safari,我个人感觉这可能是浏览器的问题,而不是你的代码。

不好意思,这只是桌面版本。我理解移动版的限制。 - pianoman
如果能引用或描述链接中的内容就好了,因为现在它已经404了。 - Djave
链接存档 https://web.archive.org/web/20201028094058/http://www.ibm.com/developerworks/library/wa-ioshtml5/ - claptimes

1

也许对您有帮助的是使用Web Audio API https://www.html5rocks.com/en/tutorials/webaudio/intro/ 它具有增益(而不是音量)控制。它对于所有浏览器都很统一(但是,IE不支持它)

  • 使用html5 / web audio API上的抽象层,如https://howlerjs.com/
  • 我可以看到的最终选择-将您的html5音频传递给WebAudio API源并使用JS控制增益(您可以在此处找到更多详细信息)这与选项#1几乎相同,但几乎不需要更改您的代码。

我已经实现了这个解决方案。它在iOS设备上运行良好。你可以通过Gainnode来控制音频。 - Raghavendra N

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接