Rails link_to and audio_tag

5

我正在尝试找到在Rails中使用link_to标签时以HTML5方式播放wav文件的最佳方法。

这是一个来自我的视图之一的样例link_to:

<%= link_to 'At Station', at_station_mdt_index_path, :class => 'btn btn-success btn-medium', :method => :put, :remote => true %>

我希望了解如何使用audio_tag在按钮被按下时触发声音。我尝试将audio_tag与link_to ERB结合使用,但出现了各种语法错误。如果有示例,将不胜感激。
更新01/04/14-10:18am CT:声音能够正确地播放一次。但是,自从在link_to中添加了:id之后,链接不再触发Rails路径以更改对象,只会播放声音。
查看代码:
    <%= link_to 'En Route', en_route_mdt_index_path(:call_id => call.id), :class => 'btn btn-warning btn-medium', :method => :put, :remote => true, :id => "er" %>
            <%= link_to 'On Scene', on_scene_mdt_index_path(:call_id => call.id), :id => 'to', :class => 'btn btn-primary btn-medium', :method => :put, :remote => true, :id => "os"  %>
            <%= link_to 'To Hospital', to_hospital_mdt_index_path(:call_id => call.id), :class => 'btn btn-warning btn-medium', :method => :put, :remote => true, :id => "to" %>

 <audio id="en-route" class="audio_player" preload="true">
    <source src="audios/en-route.wav" type="audio/wav">
</audio>

<audio id="on-scene" class="audio_player" preload="true">
    <source src="audios/on-scene.wav" type="audio/wav">
</audio>

<audio id="to-hospital" class="audio_player" preload="true">
    <source src="audios/to-hospital.wav" type="audio/wav">
</audio>

<script>
$('#er').click(function (e) {
    e.preventDefault();
    $('#en-route')[0].currentTime = 0;
    $('#en-route')[0].play();
    return true;

});

$('#os').click(function (e) {
    e.preventDefault();
    $('#on-scene')[0].currentTime = 0;
    $('#on-scene')[0].play();
    return true;

});

$('#to').click(function (e) {
    e.preventDefault();
    $('#to-hospital')[0].currentTime = 0;
    $('#to-hospital')[0].play();
    return true;

});
</script>
3个回答

5
以下是一个播放wav文件的简单示例:

http://jsfiddle.net/84pav/

HTML:
<a href="javascript:void(0)" id="playsound">At Station</a>

<audio id="sound_effect" class="audio_player" preload="auto">
    <source src="http://www.villagegeek.com/downloads/webwavs/alrighty.wav" type="audio/wav">
</audio>

JavaScript:

$('#playsound').click(function (e) {
    $('#sound_effect')[0].currentTime = 0;
    $('#sound_effect')[0].play();
    return false;
});

在播放之前,我设置currentTime = 0以确保它总是从头开始播放。

在IE上无法运行,因为IE不支持wav文件。


我尝试将音频元素和JavaScript移动到局部文件中。即使使用正确的ID元素区分两个链接,页面上的任何链接都会触发两个声音。而且当index.html.erb JavaScript每10秒重新加载时,它会同时播放两个声音。我已经复制了我的当前代码供您查看。 - nulltek
点击链接后,它会播放声音并调用URL。这是你想要的吗? - Tyler Nguyen
@TylerNguyen 是的,我想要它播放声音并通过ajax调用URL。当前的代码(我在原始问题中更新了)可以正确地触发声音,但是一旦我向link_to标签添加了:id元素,它就不会调用URL。 - nulltek
你可以删除点击处理程序中的“return false;”行,以使链接起作用。 - Tyler Nguyen
@TylerNguyen 移除 "return false;" 使得链接可以正常工作。但是一旦局部刷新完成后,声音不再触发,在控制台中会出现错误信息 "Uncaught InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable." - nulltek
显示剩余9条评论

1
我在这个回答中做了一些假设:
  1. 您正在使用HTML5标记
  2. 您想要一个样式化的链接“按钮”来触发声音
  3. 您不想显示默认的HTML5音频播放器
  4. 声音文件存储在public/audios
  5. 页面上预加载了声音文件
不幸的是,Rails 3.2实现的audio_tag存在问题(https://github.com/rails/rails/issues/9373)。所以,除非您使用Rails 4,否则最好使用实际的HTML标记。
在此示例中,我们正在加载一个mp3文件到默认的HTML5音频播放器中。以下代码片段应该在您的视图文件中。
<audio id="sound_effect" class="audio_player" controls="false" preload="true">
  <source src="/audios/TrainWhistle.mp3" type="audio/mpeg">
</audio>

由于 HTML5 音频播放器自带 "内置" 显示 chrome,您可能希望使用 CSS 将其定位到页面外。在此示例中,您需要将以下内容添加到 CSS 文件中:
.audio_player {
  position: absolute;
  top: -999em;
{

您的link_to标记大概是这样的:

<%= link_to 'At Station', '#', class: 'btn btn-success btn-medium', id: 'playsound' %>

实际播放声音的JavaScript代码将类似于以下jQuery示例:
$('#playsound').on('click', function (e) {
  e.preventDefault();
  $('#sound_effect').currentTime = 0;
  $('#sound_effect').play();
  return false;
});

这个示例可以通过对link_to标签和JavaScript进行小修改,轻松支持多个文件。

谢谢,这是正确的方向。我已经编辑了代码以反映我的设置(我正在使用公共/音频目录中的wav文件)。CSS确实隐藏了音频播放器,这很好。我已经取消隐藏它,以查看发生了什么,因为当我点击link_to时,它没有播放任何东西。它只是非常快地跳过文件。有什么想法吗?我已编辑你上面的代码示例以反映我的配置。 - nulltek
当我取消隐藏audio_player类并尝试播放时,什么也不会发生。它只是非常快速地跳过文件。此外,无论是否启用控件,音量图标都带有斜线。顺便说一下,我正在使用Chrome。尽管此功能将用于iOS Safari。 - nulltek
你能否贴一个链接吗?这可能有助于调试。 - jrmyward
我只有在开发环境中有这个。它还没有部署到生产环境。很抱歉给您带来麻烦。 - nulltek
强制让声音始终从开头播放并不是一个坏主意。我也会在我的答案中更新这个建议。这可能会解决“高速”播放的问题。 - jrmyward

-1

这样怎么样?

function playSound(soundfile) {
  document.getElementById("playsound").innerHTML=
  "<embed src=\""+soundfile+"\" hidden=\"true\" autostart=\"true\" loop=\"false\" />";
}

$('#playsound').observe('click', function (event) {
  playSound('URL to soundfile');
  event.stop(); // Prevent link from following through to its given href
});

然后将playsound的ID添加到您的链接中。


谢谢你提供的 JS。我尝试了一下,但是浏览器控制台提示 Uncaught TypeError: Object [object Object] has no method 'observe',而且声音也没有触发。我已经按照你的建议更新了代码,以防我的语法有误。 - nulltek
我无法在本地尝试它,这个示例主要是为了展示概念,你可能需要稍微调整一下才能让它适用于你。 - Donovan
我正在努力,但是我对JS / jQuery不熟悉。我需要找到更多的示例,以便更好地理解并使其正常工作。我快被折磨疯了。 - nulltek

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