Il relay HLS→RTMPS resta sul worker/agent del nodo assegnato, così tre dirette contemporanee restano in onda sul sito e sul canale della società senza schermo nero. Co-authored-by: Cursor <cursoragent@cursor.com>
103 lines
3.4 KiB
Ruby
103 lines
3.4 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "rails_helper"
|
|
|
|
RSpec.describe "HLS proxy", type: :request do
|
|
let(:mediamtx_hls) { "http://mediamtx.test:8888" }
|
|
let(:session_id) { "cc7e90b2-c672-4401-b5d3-51fdcdc7a214" }
|
|
let(:playlist) do
|
|
<<~M3U8
|
|
#EXTM3U
|
|
#EXT-X-VERSION:3
|
|
#EXT-X-TARGETDURATION:1
|
|
#EXTINF:1.0,
|
|
/live/match_#{session_id}/segment0.ts
|
|
M3U8
|
|
end
|
|
|
|
def stub_hls_get(url, status:, body: "", headers: {}, location: nil)
|
|
response_headers = headers.dup
|
|
response_headers["location"] = location if location
|
|
faraday_response = instance_double(
|
|
Faraday::Response,
|
|
status: status,
|
|
body: body,
|
|
headers: response_headers
|
|
)
|
|
conn = instance_double(Faraday::Connection)
|
|
allow_any_instance_of(HlsProxyController).to receive(:hls_conn).and_return(conn)
|
|
allow(conn).to receive(:get) do |requested, &block|
|
|
expect(requested).to start_with(url.split("?").first)
|
|
block&.call(instance_double(Faraday::Request, headers: {}))
|
|
faraday_response
|
|
end
|
|
end
|
|
|
|
before do
|
|
allow(MatchLiveTv).to receive(:mediamtx_hls_url).and_return(mediamtx_hls)
|
|
end
|
|
|
|
describe "GET /live/match_:session_id/*" do
|
|
it "rewrites playlist paths to /hls/" do
|
|
stub_hls_get(
|
|
"#{mediamtx_hls}/live/match_#{session_id}/index.m3u8",
|
|
status: 200,
|
|
body: playlist,
|
|
headers: { "content-type" => "application/vnd.apple.mpegurl" }
|
|
)
|
|
|
|
get "/live/match_#{session_id}/index.m3u8"
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
expect(response.body).to include("/hls/live/match_#{session_id}/segment0.ts")
|
|
end
|
|
end
|
|
|
|
describe "GET /hls/live/match_:id on a lab node" do
|
|
let!(:lab) do
|
|
StreamNode.create!(
|
|
slug: "ingest-lab-hls-spec",
|
|
hostname: "ingest-lab-hls-spec.lab.mltv-stream.net",
|
|
role: "lab",
|
|
status: "ready",
|
|
provider: "local",
|
|
rtmp_base_url: "rtmp://127.0.0.1:11935",
|
|
hls_base_url: "http://localhost:3000/hls",
|
|
api_base_url: "http://mediamtx_lab:9997",
|
|
internal_rtmp_url: "rtmp://mediamtx_lab:1935",
|
|
internal_hls_url: "http://mediamtx_lab:8888"
|
|
)
|
|
end
|
|
|
|
before do
|
|
user = User.create!(email: "hls-lab@test.com", name: "H", password: "Password123", role: "coach")
|
|
club = Club.create!(name: "HlsLab", sport: "volleyball")
|
|
team = club.teams.create!(name: "T", sport: "volleyball", slug: "hls-lab-t")
|
|
match = team.matches.create!(opponent_name: "X")
|
|
StreamSession.create!(id: session_id, match: match, user: user, platform: "matchlivetv", stream_node: lab)
|
|
end
|
|
|
|
it "proxies HLS to the session MediaMTX, not home" do
|
|
requested = []
|
|
faraday_response = instance_double(
|
|
Faraday::Response,
|
|
status: 200,
|
|
body: playlist,
|
|
headers: { "content-type" => "application/vnd.apple.mpegurl" }
|
|
)
|
|
conn = instance_double(Faraday::Connection)
|
|
allow_any_instance_of(HlsProxyController).to receive(:hls_conn).and_return(conn)
|
|
allow(conn).to receive(:get) do |url, &block|
|
|
requested << url
|
|
block&.call(instance_double(Faraday::Request, headers: {}))
|
|
faraday_response
|
|
end
|
|
|
|
get "/hls/live/match_#{session_id}/index.m3u8"
|
|
|
|
expect(response).to have_http_status(:ok)
|
|
expect(requested.first).to eq("http://mediamtx_lab:8888/live/match_#{session_id}/index.m3u8")
|
|
end
|
|
end
|
|
end
|