miniradio_server 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +12 -1
- data/lib/miniradio_server/app.rb +30 -1
- data/lib/miniradio_server/templ/index.html.slim +50 -0
- data/lib/miniradio_server/version.rb +1 -1
- data/lib/miniradio_server.rb +2 -2
- data/lib/public/style/main.css +26 -0
- metadata +45 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f70ca64739dfbd93c1badac47fb27cfde9a116c7386284f80becd71c018f091d
|
4
|
+
data.tar.gz: 9232efa32e08339a155806b2e986c93310840c2d4ad48f6f57adb01227463d2c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2faf237ac46476883a6a5299d5da982d45c9fbb547154871c60587237bde37a6d9b66ae45cd7db2127736d37c7d0e3a8509730e0fd5c51fa12b5fa20e9fc28ed
|
7
|
+
data.tar.gz: 6ae6dabe71bb1d51ba29f60c1c2f2389b1029a9657c19a3e5558c342db6884f5cd1f324762988a62bb39e6e9fb5271ee7f1b83401d6ba4bbe3b3d855b6e93d8d
|
data/README.md
CHANGED
@@ -39,6 +39,10 @@ Press Ctrl+C to stop.
|
|
39
39
|
|
40
40
|
The server will run in the foreground. Press Ctrl+C to stop it.
|
41
41
|
|
42
|
+
## Usage: Accessing the Index Page
|
43
|
+
|
44
|
+
You can access the index page listing available MP3 files by navigating to `http://localhost:{SERVER_PORT}/` in your web browser.
|
45
|
+
|
42
46
|
## Usage: Accessing Streams
|
43
47
|
|
44
48
|
Once the server is running, you can access the HLS streams using an HLS-compatible player (like VLC, QuickTime Player on macOS/iOS, Safari, or web players using hls.js).
|
@@ -101,7 +105,14 @@ bin/miniradio_server
|
|
101
105
|
|
102
106
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
103
107
|
|
104
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
108
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org/gems/miniradio_server).
|
109
|
+
|
110
|
+
## ToDo
|
111
|
+
|
112
|
+
* Continuous playback of multiple Music tracks
|
113
|
+
* :white_check_mark: ~~Use hls.js to support playback in Chrome.~~
|
114
|
+
* :white_check_mark: ~~Rendering of the Delivered Music list page~~
|
115
|
+
* :white_check_mark: ~~Multilingual support for file names.~~
|
105
116
|
|
106
117
|
## Contributing
|
107
118
|
|
data/lib/miniradio_server/app.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
# -*- coding: utf-8 -*-
|
2
2
|
require 'rack'
|
3
3
|
require 'open3' # Used in convert_to_hls
|
4
|
+
require 'tilt/slim'
|
5
|
+
require 'mp3info'
|
6
|
+
require 'json'
|
4
7
|
|
5
8
|
# Required to use the handler from Rack 3+
|
6
9
|
# You might need to run: gem install rackup
|
@@ -23,6 +26,12 @@ module MiniradioServer
|
|
23
26
|
request_path = env['PATH_INFO']
|
24
27
|
@logger.info "Request received: #{request_path}"
|
25
28
|
|
29
|
+
# Root URL
|
30
|
+
match = request_path.match(%r{^/$|^/index(\.html)$})
|
31
|
+
if match
|
32
|
+
return response(200, index, 'text/html')
|
33
|
+
end
|
34
|
+
|
26
35
|
# Path pattern: /stream/{mp3_basename}/{playlist or segment}
|
27
36
|
# mp3_basename is the filename without the extension
|
28
37
|
match = request_path.match(%r{^/stream/([^/]+)/(.+\.(m3u8|mp3))$})
|
@@ -32,7 +41,7 @@ module MiniradioServer
|
|
32
41
|
return not_found_response("Not Found (Invalid Path Format)")
|
33
42
|
end
|
34
43
|
|
35
|
-
mp3_basename = match[1] # e.g., "your_music" (without extension)
|
44
|
+
mp3_basename = URI.decode_uri_component(match[1]) # e.g., "your_music" (without extension)
|
36
45
|
requested_filename = match[2] # e.g., "playlist.m3u8" or "segment001.mp3"
|
37
46
|
extension = match[3].downcase # "m3u8" or "mp3"
|
38
47
|
|
@@ -102,6 +111,26 @@ module MiniradioServer
|
|
102
111
|
return internal_server_error_response
|
103
112
|
end
|
104
113
|
|
114
|
+
def get_mp3_list
|
115
|
+
r = []
|
116
|
+
@mp3_dir.glob("*.mp3").each do |file|
|
117
|
+
mp3 = {}
|
118
|
+
Mp3Info.open(file) do |mp3info|
|
119
|
+
mp3[:title] = mp3info.tag.title
|
120
|
+
mp3[:artist] = mp3info.tag.artist
|
121
|
+
mp3[:album] = mp3info.tag.album
|
122
|
+
mp3[:file] = file.basename(".mp3")
|
123
|
+
end
|
124
|
+
r << mp3
|
125
|
+
end
|
126
|
+
r
|
127
|
+
end
|
128
|
+
|
129
|
+
def index
|
130
|
+
template = Tilt::SlimTemplate.new("#{__dir__}/templ/index.html.slim")
|
131
|
+
template.render(self, :mp3_list => get_mp3_list)
|
132
|
+
end
|
133
|
+
|
105
134
|
private
|
106
135
|
|
107
136
|
# Check if HLS conversion is needed and execute if necessary (with lock)
|
@@ -0,0 +1,50 @@
|
|
1
|
+
doctype html
|
2
|
+
html
|
3
|
+
head
|
4
|
+
meta charset="UTF-8"
|
5
|
+
meta name="viewport" content="width=device-width, initial-scale=1.0"
|
6
|
+
title Miniradio Server
|
7
|
+
link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css" type="text/css"
|
8
|
+
link rel="stylesheet" href="style/main.css" type="text/css"
|
9
|
+
script src="https://cdn.jsdelivr.net/npm/hls.js@1"
|
10
|
+
body
|
11
|
+
h1 Straming List
|
12
|
+
table.compact.striped
|
13
|
+
thead
|
14
|
+
tr
|
15
|
+
th scope="col" Play
|
16
|
+
th scope="col" Title
|
17
|
+
th scope="col" Artist
|
18
|
+
th scope="col" Album
|
19
|
+
tbody
|
20
|
+
- mp3_list.each_with_index do |mp3, i|
|
21
|
+
tr
|
22
|
+
td
|
23
|
+
audio controls=true id='audio-#{i+1}'
|
24
|
+
td=mp3[:title] || mp3[:file]
|
25
|
+
td=mp3[:artist]
|
26
|
+
td=mp3[:album]
|
27
|
+
javascript:
|
28
|
+
function setupHLS(audioElementId, streamUrl) {
|
29
|
+
const audio = document.getElementById(audioElementId);
|
30
|
+
|
31
|
+
if (Hls.isSupported()) {
|
32
|
+
const hls = new Hls();
|
33
|
+
hls.loadSource(streamUrl);
|
34
|
+
hls.attachMedia(audio);
|
35
|
+
hls.on(Hls.Events.MANIFEST_PARSED, function () {
|
36
|
+
console.log(`${audioElementId} loaded`);
|
37
|
+
});
|
38
|
+
} else if (audio.canPlayType('application/vnd.apple.mpegurl')) {
|
39
|
+
// HLS native support browser. ex.Safari
|
40
|
+
audio.src = streamUrl;
|
41
|
+
} else {
|
42
|
+
console.error('This browser cannot play HLS.');
|
43
|
+
}
|
44
|
+
}
|
45
|
+
var mp3s = #{{JSON.generate(mp3_list)}};
|
46
|
+
for (let i = 0; i < mp3s.length; i++) {
|
47
|
+
setupHLS(`audio-${i+1}`, `/stream/${mp3s[i].file}/playlist.m3u8`);
|
48
|
+
}
|
49
|
+
hr
|
50
|
+
p Miniradio ver #{MiniradioServer::VERSION}
|
data/lib/miniradio_server.rb
CHANGED
@@ -70,7 +70,7 @@ if __FILE__ == $PROGRAM_NAME || 'bin/miniradio_server' == $PROGRAM_NAME || 'mini
|
|
70
70
|
puts "MP3 Source Directory: #{MiniradioServer::MP3_SRC_DIR}"
|
71
71
|
puts "HLS Cache Directory: #{MiniradioServer::HLS_CACHE_DIR}"
|
72
72
|
puts "Default External Encoding: #{Encoding.default_external}" # For confirmation log
|
73
|
-
puts "
|
73
|
+
puts "Server URL: http://localhost:9292"
|
74
74
|
puts "Example Streaming URL: http://localhost:#{MiniradioServer::SERVER_PORT}/stream/{mp3_filename_without_extension}/playlist.m3u8"
|
75
75
|
puts "e.g., If mp3_files/ contains my_music.mp3 -> http://localhost:#{MiniradioServer::SERVER_PORT}/stream/my_music/playlist.m3u8"
|
76
76
|
puts "Press Ctrl+C to stop."
|
@@ -78,7 +78,7 @@ if __FILE__ == $PROGRAM_NAME || 'bin/miniradio_server' == $PROGRAM_NAME || 'mini
|
|
78
78
|
begin
|
79
79
|
# Use Rackup::Handler::WEBrick, recommended for Rack 3+
|
80
80
|
Rackup::Handler::WEBrick.run(
|
81
|
-
app,
|
81
|
+
Rack::Static.new(app, urls: ["/style", "/images"], root: "#{__dir__}/public"),
|
82
82
|
Port: MiniradioServer::SERVER_PORT,
|
83
83
|
Logger: logger, # Share logger with WEBrick
|
84
84
|
AccessLog: [] # Disable WEBrick's own access log (logging handled by Rack app)
|
@@ -0,0 +1,26 @@
|
|
1
|
+
@charset "utf-8";
|
2
|
+
|
3
|
+
table.compact td, table.compact th {
|
4
|
+
padding: 0.4rem 0.5rem;
|
5
|
+
font-size: 0.9rem;
|
6
|
+
line-height: 1.2;
|
7
|
+
}
|
8
|
+
@media screen and (max-width: 600px) {
|
9
|
+
table thead {
|
10
|
+
display: none;
|
11
|
+
}
|
12
|
+
table tr {
|
13
|
+
display: block;
|
14
|
+
margin-bottom: 0.8rem;
|
15
|
+
}
|
16
|
+
table td {
|
17
|
+
display: flex;
|
18
|
+
justify-content: space-between;
|
19
|
+
padding: 0.3rem 0;
|
20
|
+
border-bottom: 1px solid #ccc;
|
21
|
+
}
|
22
|
+
table td::before {
|
23
|
+
content: attr(data-label);
|
24
|
+
font-weight: bold;
|
25
|
+
}
|
26
|
+
}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: miniradio_server
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Koichiro Ohba
|
@@ -107,6 +107,48 @@ dependencies:
|
|
107
107
|
- - ">="
|
108
108
|
- !ruby/object:Gem::Version
|
109
109
|
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: tilt
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
type: :runtime
|
118
|
+
prerelease: false
|
119
|
+
version_requirements: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: '0'
|
124
|
+
- !ruby/object:Gem::Dependency
|
125
|
+
name: slim
|
126
|
+
requirement: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - ">="
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
type: :runtime
|
132
|
+
prerelease: false
|
133
|
+
version_requirements: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
- !ruby/object:Gem::Dependency
|
139
|
+
name: mp3info
|
140
|
+
requirement: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
type: :runtime
|
146
|
+
prerelease: false
|
147
|
+
version_requirements: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
110
152
|
description: |2
|
111
153
|
This is a basic HTTP Live Streaming (HLS) server written in Ruby using the Rack interface. It serves MP3 audio files by converting them on-the-fly into HLS format (M3U8 playlist and MP3 segment files) using `ffmpeg`. Converted files are cached for subsequent requests.
|
112
154
|
This server is designed for simplicity and primarily targets Video on Demand (VOD) scenarios where you want to stream existing MP3 files via HLS without pre-converting them.
|
@@ -122,7 +164,9 @@ files:
|
|
122
164
|
- hls_cache/.gitkeep
|
123
165
|
- lib/miniradio_server.rb
|
124
166
|
- lib/miniradio_server/app.rb
|
167
|
+
- lib/miniradio_server/templ/index.html.slim
|
125
168
|
- lib/miniradio_server/version.rb
|
169
|
+
- lib/public/style/main.css
|
126
170
|
- mp3_files/.gitkeep
|
127
171
|
- sig/miniradio_server.rbs
|
128
172
|
homepage: https://github.com/koichiro/miniradio_server
|