Skip to content

Commit 5ddc4bb

Browse files
committedJan 18, 2025
add new expert handler 'H=E' which calls a script to determine the commandline for FFmpeg or vlc
1 parent 61dbec6 commit 5ddc4bb

7 files changed

+441
-83
lines changed
 

‎README

+2
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,10 @@ Configuration:
111111
| | | | | M3US:
112112
| | | | | STREAM: H=F uses ffmpeg
113113
| | | | | H=V uses vlc
114+
| | | | | H=E calls the script iptv-cmdline-expert.py to get the commandline
114115
| | | | | RADIO: H=F uses ffmpeg
115116
| | | | | H=V uses vlc
117+
| | | | | H=E calls the script iptv-cmdline-expert.py to get the commandline
116118
| | | | Stream address
117119
| | | | UDP: multicast [source@]group address
118120
| | | | CURL: HTTP/HTTPS URL; colons (%3A) and pipes (%7C) shall be URL encoded

‎iptv/iptv-cmdline-expert.py

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#!/usr/bin/python3
2+
3+
import sys
4+
import json
5+
6+
def readJson(str):
7+
return json.loads(str)
8+
9+
def prepareFFmpegVideo(json_object):
10+
# begin command line
11+
result = "ffmpeg -hide_banner -re -y" + \
12+
" -thread_queue_size " + str(json_object["threads"]) + \
13+
" -i \"" + json_object["url"] + "\""
14+
15+
# add audio urls if they exists
16+
if 'audiourl' in json_object:
17+
for aurl in json_object['audiourl']:
18+
result += " -thread_queue_size " + str(json_object["threads"]) + \
19+
" -i \"" + aurl + "\""
20+
21+
# copy video
22+
result += " -c:v copy"
23+
24+
# copy audio
25+
result += " -c:a copy"
26+
27+
# copy subtitles
28+
# result += " -c:s copy"
29+
30+
# map video/audio stream
31+
if 'audiourl' in json_object:
32+
i = 1
33+
result += " -map 0:v"
34+
for aurl in json_object['audiourl']:
35+
result += " -map " + str(i) + ":a"
36+
i += 1
37+
38+
# add video pid
39+
result += " -streamid 0:" + str(json_object["vpid"])
40+
41+
# add audio pid
42+
i = 1
43+
for apid in json_object['apid']:
44+
result += " -streamid " + str(i) + ":" + str(apid)
45+
i += 1
46+
47+
# add all other parameters
48+
result += " -f mpegts"
49+
result += " -mpegts_transport_stream_id " + str(json_object["tpid"])
50+
result += " -mpegts_pmt_start_pid 4096"
51+
result += " -mpegts_service_id " + str(json_object["spid"])
52+
result += " -mpegts_original_network_id " + str(json_object["nid"])
53+
result += " -mpegts_flags system_b"
54+
# result += " -mpegts_flags nit"
55+
result += " -metadata service_name=\"" + json_object["channelName"] + "\""
56+
57+
# print ts stream to stdout
58+
result += " pipe:1"
59+
60+
return result
61+
62+
def prepareFFmpegAudio(json_object):
63+
# begin command line
64+
result = "ffmpeg -hide_banner -re -y" + \
65+
" -thread_queue_size " + str(json_object["threads"]) + \
66+
" -i \"" + json_object["url"] + "\""
67+
68+
# copy audio
69+
result += " -c:a copy"
70+
71+
# add audio pid
72+
i = 0
73+
for apid in json_object['apid']:
74+
result += " -streamid " + str(i) + ":" + str(apid)
75+
i += 1
76+
77+
# add all other parameters
78+
result += " -f mpegts"
79+
result += " -mpegts_transport_stream_id " + str(json_object["tpid"])
80+
result += " -mpegts_pmt_start_pid 4096"
81+
result += " -mpegts_service_id " + str(json_object["spid"])
82+
result += " -mpegts_original_network_id " + str(json_object["nid"])
83+
result += " -mpegts_flags system_b"
84+
# result += " -mpegts_flags nit"
85+
result += " -metadata service_name=\"" + json_object["channelName"] + "\""
86+
87+
# print ts stream to stdout
88+
result += " pipe:1"
89+
90+
return result
91+
92+
def prepareVlcVideo(json_object):
93+
result = "vlc" + " -I" + " dummy" + " -v" + \
94+
" --network-caching=4000" + " --live-caching" + " 2000" + \
95+
" --http-reconnect" + " --http-user-agent=Mozilla/5.0" + \
96+
" --adaptive-logic" + " highest"
97+
98+
result += " \"" + json_object["url"] + "\""
99+
result += " --sout"
100+
result += " \"#standard{access=file,mux=ts{use-key-frames,pid-video=" + \
101+
str(json_object["vpid"]) + ",pid-audio=" + str(json_object["apid"][0]) + ",pid-spu=4096,tsid="+ str(json_object["tpid"]) + "},dst=-}\""
102+
103+
return result
104+
105+
def prepareVlcAudio(json_object):
106+
result = "vlc" + " -I" + " dummy" + " --verbose=2" + " --no-stats"
107+
result += " \"" + json_object["url"] + "\""
108+
result += " --sout"
109+
result += " \"#transcode{acodec=mpga,ab=320}:standard{access=file,mux=ts{pid-audio=" + str(json_object["apid"][0]) + ",pid-spu=4096,tsid=" + str(json_object["tpid"]) + "},dst=-}\""
110+
111+
return result
112+
113+
114+
if __name__ == '__main__':
115+
json_object = readJson(sys.argv[2])
116+
# print(json.dumps(json_object, indent=4))
117+
118+
# Copy of the FFmpeg/vlc calls in vdr-plugin-iptv
119+
# Do whatever you want to do. E.g change frame rate, reencode audio, ...
120+
# It's your your choice to change the FFmpeg or vlc command line
121+
if sys.argv[1] == '1':
122+
print(prepareFFmpegVideo(json_object))
123+
else:
124+
print(prepareVlcAudio(json_object))
125+
126+
127+
128+

‎m3u8handler.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ m3u_stream M3u8Handler::parseM3u(const std::string &webUri, int useYtdlp) {
281281
result.vpid = -1;
282282
result.spid = -1;
283283
result.tpid = -1;
284+
result.nid = -1;
284285
result.apids.clear();
285286

286287
return result;

‎protocolradio.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ bool cIptvProtocolRadio::Open() {
4040
streams.vpid = 0;
4141
streams.spid = Channel->Sid();
4242
streams.tpid = Channel->Tid();
43+
streams.nid = Channel->Nid();
4344

4445
int aidx = 0;
4546
while (true) {

‎source.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ bool cIptvTransponderParameters::Parse(const char *strP) {
186186
break;
187187

188188
case 'H':
189-
if (data[0] == 'F' || data[0] == 'V') {
189+
if (data[0] == 'F' || data[0] == 'V' || data[0] == 'E') {
190190
handlerType = data[0];
191191
}
192192
break;

‎streambasehandler.cpp

+304-82
Large diffs are not rendered by default.

‎streambasehandler.h

+4
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,14 @@ class StreamBaseHandler {
3636

3737
void checkErrorOut(const std::string &msg);
3838

39+
std::string convertStreamToJson(bool hasVideo, const m3u_stream &stream);
40+
3941
protected:
4042
std::vector<std::string> prepareStreamCmdVideoFfmpeg(const m3u_stream &stream);
4143
std::vector<std::string> prepareStreamCmdAudioFfmpeg(const m3u_stream &stream);
4244

4345
std::vector<std::string> prepareStreamCmdVideoVlc(const m3u_stream &stream);
4446
std::vector<std::string> prepareStreamCmdAudioVlc(const m3u_stream &stream);
47+
48+
std::string prepareExpertCmdLine(int isVideo, const std::string &json);
4549
};

0 commit comments

Comments
 (0)
Please sign in to comment.