Ruby/Rails技术问题:使用video_tag无法播放HLS/.m3u8媒体
video_tag Hey there! Let's figure out why your .m3u8 HLS stream isn't playing when embedded with Rails' video_tag, and what fixes you can try.
First: Check Native Browser Support
Most modern browsers (Chrome, Firefox, Safari, Edge) natively support HLS (.m3u8)—so first, rule out basic configuration issues before reaching for extra tools:
- MIME Type Configuration: Your server needs to send the correct Content-Type header for .m3u8 files. In Rails, add this line to
config/initializers/mime_types.rb:
This ensures Rails serves .m3u8 files with the right header so browsers recognize them as HLS streams.Mime::Type.register "application/vnd.apple.mpegurl", :m3u8 - HTTPS Requirement: In production, most browsers block HLS streams over HTTP. Make sure your app is served over HTTPS (localhost is exempt for development).
- Valid Stream URL: Double-check that your .m3u8 URL is accessible directly (try opening it in a new tab—if it downloads instead of playing, the MIME type is likely wrong).
If Native Support Fails: Use a JavaScript Library (No Gem Needed)
If you need to support older browsers (like IE11) or run into edge cases with native playback, hls.js is the go-to solution. It's a lightweight JS library that adds HLS support to browsers that don't have it natively. Here's how to set it up:
- Add hls.js to your project—either via CDN in your layout:
Or install it via npm/yarn if you're using a bundler like Webpacker or esbuild.<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script> - Update your
video_tagand add a small JS snippet to handle playback:<%= video_tag '', controls: true, id: 'hls-video', class: 'your-class' %>document.addEventListener('DOMContentLoaded', () => { const video = document.getElementById('hls-video'); const streamUrl = '<%= your_m3u8_stream_url %>'; if (Hls.isSupported()) { const hls = new Hls(); hls.loadSource(streamUrl); hls.attachMedia(video); // Auto-play once the manifest is parsed (optional) hls.on(Hls.Events.MANIFEST_PARSED, () => { video.play().catch(err => console.error('Play error:', err)); }); } else if (video.canPlayType('application/vnd.apple.mpegurl')) { // Fallback for Safari, which has native HLS support video.src = streamUrl; video.addEventListener('loadedmetadata', () => { video.play().catch(err => console.error('Play error:', err)); }); } else { console.error('HLS is not supported by this browser'); } });
Do You Need a Ruby Gem?
Short answer: Only if you need to generate/transcode HLS streams in Rails. If you're just playing pre-existing .m3u8 files, you don't need any gems.
If you do need to transcode videos to HLS format on the backend, gems like streamio-ffmpeg (which wraps FFmpeg) can help you generate the .m3u8 playlist and segmented video files. But that's for stream creation, not playback.
内容的提问来源于stack exchange,提问作者Muhammad Rahmatullah

