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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aaaf57cfdaba5f66a068447ec813636651ddc440000f09815658f9a42c539606
4
- data.tar.gz: 05d5e7eb56654389f97e779c50376f778af460c93c1ba195f9c3998f6ca50f56
3
+ metadata.gz: f70ca64739dfbd93c1badac47fb27cfde9a116c7386284f80becd71c018f091d
4
+ data.tar.gz: 9232efa32e08339a155806b2e986c93310840c2d4ad48f6f57adb01227463d2c
5
5
  SHA512:
6
- metadata.gz: 6ce3d244968874b6a9810e13f0f2ffbeeb7d1a7cc76531ffefa71a3cbdbe6e03828861456386cf1a7e68e4e50321c527e20bd646dbfeb7d1082c03e5354609d2
7
- data.tar.gz: ceed1b93aeded65a534581dc185d5413bbdf8e90869d1abbe56419d76fa4cba6406071a127a8370bdff9f17c0441efe2fc1460b2da3462b88a102c7f0a5b7b6a
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
 
@@ -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}
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MiniradioServer
4
- VERSION = "0.0.1"
4
+ VERSION = "0.0.3"
5
5
  end
@@ -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 "Using Handler: Rackup::Handler::WEBrick" # For confirmation log
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.1
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