Prompt for AirPlay mirror setup and enable gated HLS video reception

This commit is contained in:
toorux committed 2026-10-10 01:11:54 +08:00
1 parent 87ab0ad431
commit f78bf2f0ee
3 files changed
+48 -1

No files matched your search

+46
View File
@@ -77,3 +77,49 @@ if 'framely_media_kind' not in s:
p.write_text(s)
from shutil import copyfile
copyfile(Path(__file__).parent/'native/frame_sink.h',p.parent/'framely/frame_sink.h')
# A mirror SETUP is already an explicit video request; do not wait for sound
# or the first codec packet before asking for consent.
header=p.parent/'lib/raop.h'
s=header.read_text()
if 'framely_video_setup' not in s:
marker=' void (*video_report_size)'
assert marker in s
s=s.replace(marker, ' void (*framely_video_setup)(void *cls);\n'+marker,1)
header.write_text(s)
handlers=p.parent/'lib/raop_handlers.h'
s=handlers.read_text()
if 'callbacks.framely_video_setup' not in s:
marker=' raop_rtp_mirror_start(conn->raop_rtp_mirror, &dport, raop->clientFPSdata);'
assert marker in s
s=s.replace(marker,marker+'\n if (raop->callbacks.framely_video_setup) raop->callbacks.framely_video_setup(raop->callbacks.cls);',1)
handlers.write_text(s)
s=p.read_text()
if 'extern "C" void framely_video_setup' not in s:
marker='extern "C" void video_report_size('
at=s.index(marker)
s=s[:at]+'''extern "C" void framely_video_setup(void *cls) {
const char* directory=getenv("FRAMELY_CAST_DIR"),*id=getenv("FRAMELY_CAST_ID");
if(directory&&id)FrameSink(directory,id,"AirPlay").event("request",0,0,"video");
}
'''+s[at:]
marker=' raop_cbs.video_report_size = video_report_size;'
assert marker in s
s=s.replace(marker,marker+'\n raop_cbs.framely_video_setup = framely_video_setup;',1)
p.write_text(s)
# HLS uses playbin's separate audio sink; apply the same consent gate there.
renderer=p.parent/'renderers/video_renderer.c'
s=renderer.read_text()
if 'Framely HLS consent' not in s:
marker=' g_object_set(G_OBJECT (renderer_type[i]->pipeline), "video-sink", playbin_videosink, NULL);'
assert marker in s
s=s.replace(marker,marker+'''
/* Framely HLS consent: audio must use the accepted session too. */
if (!strcmp(videosink, "framelyvideosink")) {
GstElement *audio = gst_element_factory_make("framelyaudiosink", NULL);
g_assert(audio);
g_object_set(renderer_type[i]->pipeline, "audio-sink", audio, NULL);
}
''',1)
renderer.write_text(s)
+1
View File
@@ -179,6 +179,7 @@ impl Receivers {
"-n",
name,
"-avdec",
"-hls",
"-vs",
"framelyvideosink",
"-as",
+1 -1
View File
@@ -9,7 +9,7 @@ binaries=Path(args.binaries).resolve()
with tempfile.TemporaryDirectory(prefix='framely-media-test-') as directory:
root=Path(directory);events=socket.socket(socket.AF_UNIX,socket.SOCK_DGRAM);events.bind(str(root/'events.sock'));events.settimeout(5)
token='0123456789abcdef0123456789abcdef';env=dict(os.environ,GST_PLUGIN_PATH=str(binaries),FRAMELY_CAST_DIR=directory,FRAMELY_CAST_ID=token)
airplay=subprocess.Popen([str(binaries/'uxplay'),'-n','Framely test','-avdec','-vs','framelyvideosink','-as','framelyaudiosink'],env=env,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
airplay=subprocess.Popen([str(binaries/'uxplay'),'-n','Framely test','-avdec','-hls','-vs','framelyvideosink','-as','framelyaudiosink'],env=env,stdout=subprocess.PIPE,stderr=subprocess.STDOUT)
try:
time.sleep(2);assert airplay.poll() is None,airplay.stdout.read().decode()
print('PASS: UxPlay starts with bundled decoders and consent sinks')