StreamingCommunity 2.5.2__py3-none-any.whl → 2.5.5__py3-none-any.whl

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.

Potentially problematic release.


This version of StreamingCommunity might be problematic. Click here for more details.

Files changed (268) hide show
  1. StreamingCommunity/Api/Player/Helper/Vixcloud/js_parser.py +143 -143
  2. StreamingCommunity/Api/Player/Helper/Vixcloud/util.py +136 -136
  3. StreamingCommunity/Api/Player/ddl.py +89 -89
  4. StreamingCommunity/Api/Player/maxstream.py +151 -151
  5. StreamingCommunity/Api/Player/supervideo.py +193 -193
  6. StreamingCommunity/Api/Player/vixcloud.py +272 -272
  7. StreamingCommunity/Api/Site/1337xx/__init__.py +51 -50
  8. StreamingCommunity/Api/Site/1337xx/costant.py +14 -14
  9. StreamingCommunity/Api/Site/1337xx/site.py +87 -89
  10. StreamingCommunity/Api/Site/1337xx/title.py +63 -64
  11. StreamingCommunity/Api/Site/altadefinizionegratis/__init__.py +74 -50
  12. StreamingCommunity/Api/Site/altadefinizionegratis/costant.py +21 -19
  13. StreamingCommunity/Api/Site/altadefinizionegratis/film.py +81 -72
  14. StreamingCommunity/Api/Site/altadefinizionegratis/site.py +116 -94
  15. StreamingCommunity/Api/Site/animeunity/__init__.py +75 -50
  16. StreamingCommunity/Api/Site/animeunity/costant.py +21 -19
  17. StreamingCommunity/Api/Site/animeunity/film_serie.py +171 -134
  18. StreamingCommunity/Api/Site/animeunity/site.py +191 -174
  19. StreamingCommunity/Api/Site/animeunity/util/ScrapeSerie.py +97 -97
  20. StreamingCommunity/Api/Site/cb01new/__init__.py +51 -51
  21. StreamingCommunity/Api/Site/cb01new/costant.py +19 -19
  22. StreamingCommunity/Api/Site/cb01new/film.py +61 -71
  23. StreamingCommunity/Api/Site/cb01new/site.py +82 -82
  24. StreamingCommunity/Api/Site/ddlstreamitaly/__init__.py +55 -55
  25. StreamingCommunity/Api/Site/ddlstreamitaly/costant.py +20 -20
  26. StreamingCommunity/Api/Site/ddlstreamitaly/series.py +149 -145
  27. StreamingCommunity/Api/Site/ddlstreamitaly/site.py +98 -98
  28. StreamingCommunity/Api/Site/ddlstreamitaly/util/ScrapeSerie.py +84 -84
  29. StreamingCommunity/Api/Site/guardaserie/__init__.py +50 -50
  30. StreamingCommunity/Api/Site/guardaserie/costant.py +19 -19
  31. StreamingCommunity/Api/Site/guardaserie/series.py +199 -198
  32. StreamingCommunity/Api/Site/guardaserie/site.py +89 -89
  33. StreamingCommunity/Api/Site/guardaserie/util/ScrapeSerie.py +110 -110
  34. StreamingCommunity/Api/Site/ilcorsaronero/__init__.py +51 -51
  35. StreamingCommunity/Api/Site/ilcorsaronero/costant.py +18 -18
  36. StreamingCommunity/Api/Site/ilcorsaronero/site.py +71 -71
  37. StreamingCommunity/Api/Site/ilcorsaronero/title.py +44 -44
  38. StreamingCommunity/Api/Site/ilcorsaronero/util/ilCorsarScraper.py +149 -149
  39. StreamingCommunity/Api/Site/mostraguarda/__init__.py +48 -48
  40. StreamingCommunity/Api/Site/mostraguarda/costant.py +18 -18
  41. StreamingCommunity/Api/Site/mostraguarda/film.py +90 -101
  42. StreamingCommunity/Api/Site/streamingcommunity/__init__.py +79 -55
  43. StreamingCommunity/Api/Site/streamingcommunity/costant.py +21 -19
  44. StreamingCommunity/Api/Site/streamingcommunity/film.py +86 -75
  45. StreamingCommunity/Api/Site/streamingcommunity/series.py +259 -207
  46. StreamingCommunity/Api/Site/streamingcommunity/site.py +156 -142
  47. StreamingCommunity/Api/Site/streamingcommunity/util/ScrapeSerie.py +124 -124
  48. StreamingCommunity/Api/Template/Class/SearchType.py +101 -101
  49. StreamingCommunity/Api/Template/Util/__init__.py +4 -4
  50. StreamingCommunity/Api/Template/Util/get_domain.py +201 -201
  51. StreamingCommunity/Api/Template/Util/manage_ep.py +178 -178
  52. StreamingCommunity/Api/Template/Util/recall_search.py +37 -37
  53. StreamingCommunity/Api/Template/__init__.py +2 -2
  54. StreamingCommunity/Api/Template/site.py +87 -87
  55. StreamingCommunity/Lib/Downloader/HLS/downloader.py +529 -1008
  56. StreamingCommunity/Lib/Downloader/HLS/proxyes.py +110 -110
  57. StreamingCommunity/Lib/Downloader/HLS/segments.py +446 -573
  58. StreamingCommunity/Lib/Downloader/MP4/downloader.py +181 -155
  59. StreamingCommunity/Lib/Downloader/TOR/downloader.py +297 -295
  60. StreamingCommunity/Lib/Downloader/__init__.py +4 -4
  61. StreamingCommunity/Lib/FFmpeg/__init__.py +4 -4
  62. StreamingCommunity/Lib/FFmpeg/capture.py +170 -170
  63. StreamingCommunity/Lib/FFmpeg/command.py +264 -296
  64. StreamingCommunity/Lib/FFmpeg/util.py +248 -248
  65. StreamingCommunity/Lib/M3U8/__init__.py +5 -5
  66. StreamingCommunity/Lib/M3U8/decryptor.py +164 -164
  67. StreamingCommunity/Lib/M3U8/estimator.py +146 -228
  68. StreamingCommunity/Lib/M3U8/parser.py +666 -666
  69. StreamingCommunity/Lib/M3U8/url_fixer.py +57 -57
  70. StreamingCommunity/Lib/TMBD/__init__.py +1 -1
  71. StreamingCommunity/Lib/TMBD/obj_tmbd.py +39 -39
  72. StreamingCommunity/Lib/TMBD/tmdb.py +345 -345
  73. StreamingCommunity/TelegramHelp/__init__.py +0 -0
  74. StreamingCommunity/TelegramHelp/request_manager.py +82 -0
  75. StreamingCommunity/TelegramHelp/session.py +56 -0
  76. StreamingCommunity/TelegramHelp/telegram_bot.py +561 -0
  77. StreamingCommunity/Upload/update.py +75 -67
  78. StreamingCommunity/Upload/version.py +5 -5
  79. StreamingCommunity/Util/_jsonConfig.py +227 -228
  80. StreamingCommunity/Util/call_stack.py +42 -42
  81. StreamingCommunity/Util/color.py +20 -20
  82. StreamingCommunity/Util/console.py +12 -12
  83. StreamingCommunity/Util/ffmpeg_installer.py +342 -370
  84. StreamingCommunity/Util/headers.py +159 -159
  85. StreamingCommunity/Util/logger.py +61 -61
  86. StreamingCommunity/Util/message.py +36 -64
  87. StreamingCommunity/Util/os.py +500 -507
  88. StreamingCommunity/Util/table.py +271 -228
  89. StreamingCommunity/run.py +352 -245
  90. {StreamingCommunity-2.5.2.dist-info → StreamingCommunity-2.5.5.dist-info}/LICENSE +674 -674
  91. {StreamingCommunity-2.5.2.dist-info → StreamingCommunity-2.5.5.dist-info}/METADATA +601 -543
  92. StreamingCommunity-2.5.5.dist-info/RECORD +96 -0
  93. {StreamingCommunity-2.5.2.dist-info → StreamingCommunity-2.5.5.dist-info}/entry_points.txt +0 -1
  94. StreamingCommunity/Api/Player/Helper/Vixcloud/__pycache__/js_parser.cpython-313.pyc +0 -0
  95. StreamingCommunity/Api/Player/Helper/Vixcloud/__pycache__/js_parser.cpython-39.pyc +0 -0
  96. StreamingCommunity/Api/Player/Helper/Vixcloud/__pycache__/util.cpython-313.pyc +0 -0
  97. StreamingCommunity/Api/Player/Helper/Vixcloud/__pycache__/util.cpython-39.pyc +0 -0
  98. StreamingCommunity/Api/Player/__pycache__/ddl.cpython-313.pyc +0 -0
  99. StreamingCommunity/Api/Player/__pycache__/ddl.cpython-39.pyc +0 -0
  100. StreamingCommunity/Api/Player/__pycache__/maxstream.cpython-313.pyc +0 -0
  101. StreamingCommunity/Api/Player/__pycache__/maxstream.cpython-39.pyc +0 -0
  102. StreamingCommunity/Api/Player/__pycache__/supervideo.cpython-313.pyc +0 -0
  103. StreamingCommunity/Api/Player/__pycache__/supervideo.cpython-39.pyc +0 -0
  104. StreamingCommunity/Api/Player/__pycache__/vixcloud.cpython-313.pyc +0 -0
  105. StreamingCommunity/Api/Player/__pycache__/vixcloud.cpython-39.pyc +0 -0
  106. StreamingCommunity/Api/Site/1337xx/__pycache__/__init__.cpython-313.pyc +0 -0
  107. StreamingCommunity/Api/Site/1337xx/__pycache__/__init__.cpython-39.pyc +0 -0
  108. StreamingCommunity/Api/Site/1337xx/__pycache__/costant.cpython-313.pyc +0 -0
  109. StreamingCommunity/Api/Site/1337xx/__pycache__/costant.cpython-39.pyc +0 -0
  110. StreamingCommunity/Api/Site/1337xx/__pycache__/site.cpython-313.pyc +0 -0
  111. StreamingCommunity/Api/Site/1337xx/__pycache__/site.cpython-39.pyc +0 -0
  112. StreamingCommunity/Api/Site/1337xx/__pycache__/title.cpython-313.pyc +0 -0
  113. StreamingCommunity/Api/Site/1337xx/__pycache__/title.cpython-39.pyc +0 -0
  114. StreamingCommunity/Api/Site/altadefinizionegratis/__pycache__/__init__.cpython-313.pyc +0 -0
  115. StreamingCommunity/Api/Site/altadefinizionegratis/__pycache__/__init__.cpython-39.pyc +0 -0
  116. StreamingCommunity/Api/Site/altadefinizionegratis/__pycache__/costant.cpython-313.pyc +0 -0
  117. StreamingCommunity/Api/Site/altadefinizionegratis/__pycache__/costant.cpython-39.pyc +0 -0
  118. StreamingCommunity/Api/Site/altadefinizionegratis/__pycache__/film.cpython-313.pyc +0 -0
  119. StreamingCommunity/Api/Site/altadefinizionegratis/__pycache__/film.cpython-39.pyc +0 -0
  120. StreamingCommunity/Api/Site/altadefinizionegratis/__pycache__/site.cpython-313.pyc +0 -0
  121. StreamingCommunity/Api/Site/altadefinizionegratis/__pycache__/site.cpython-39.pyc +0 -0
  122. StreamingCommunity/Api/Site/animeunity/__pycache__/__init__.cpython-313.pyc +0 -0
  123. StreamingCommunity/Api/Site/animeunity/__pycache__/__init__.cpython-39.pyc +0 -0
  124. StreamingCommunity/Api/Site/animeunity/__pycache__/costant.cpython-313.pyc +0 -0
  125. StreamingCommunity/Api/Site/animeunity/__pycache__/costant.cpython-39.pyc +0 -0
  126. StreamingCommunity/Api/Site/animeunity/__pycache__/film_serie.cpython-313.pyc +0 -0
  127. StreamingCommunity/Api/Site/animeunity/__pycache__/film_serie.cpython-39.pyc +0 -0
  128. StreamingCommunity/Api/Site/animeunity/__pycache__/site.cpython-313.pyc +0 -0
  129. StreamingCommunity/Api/Site/animeunity/__pycache__/site.cpython-39.pyc +0 -0
  130. StreamingCommunity/Api/Site/animeunity/util/__pycache__/ScrapeSerie.cpython-313.pyc +0 -0
  131. StreamingCommunity/Api/Site/animeunity/util/__pycache__/ScrapeSerie.cpython-39.pyc +0 -0
  132. StreamingCommunity/Api/Site/cb01new/__pycache__/__init__.cpython-313.pyc +0 -0
  133. StreamingCommunity/Api/Site/cb01new/__pycache__/__init__.cpython-39.pyc +0 -0
  134. StreamingCommunity/Api/Site/cb01new/__pycache__/costant.cpython-313.pyc +0 -0
  135. StreamingCommunity/Api/Site/cb01new/__pycache__/costant.cpython-39.pyc +0 -0
  136. StreamingCommunity/Api/Site/cb01new/__pycache__/film.cpython-313.pyc +0 -0
  137. StreamingCommunity/Api/Site/cb01new/__pycache__/film.cpython-39.pyc +0 -0
  138. StreamingCommunity/Api/Site/cb01new/__pycache__/site.cpython-313.pyc +0 -0
  139. StreamingCommunity/Api/Site/cb01new/__pycache__/site.cpython-39.pyc +0 -0
  140. StreamingCommunity/Api/Site/ddlstreamitaly/__pycache__/__init__.cpython-313.pyc +0 -0
  141. StreamingCommunity/Api/Site/ddlstreamitaly/__pycache__/__init__.cpython-39.pyc +0 -0
  142. StreamingCommunity/Api/Site/ddlstreamitaly/__pycache__/costant.cpython-313.pyc +0 -0
  143. StreamingCommunity/Api/Site/ddlstreamitaly/__pycache__/costant.cpython-39.pyc +0 -0
  144. StreamingCommunity/Api/Site/ddlstreamitaly/__pycache__/series.cpython-313.pyc +0 -0
  145. StreamingCommunity/Api/Site/ddlstreamitaly/__pycache__/series.cpython-39.pyc +0 -0
  146. StreamingCommunity/Api/Site/ddlstreamitaly/__pycache__/site.cpython-313.pyc +0 -0
  147. StreamingCommunity/Api/Site/ddlstreamitaly/__pycache__/site.cpython-39.pyc +0 -0
  148. StreamingCommunity/Api/Site/ddlstreamitaly/util/__pycache__/ScrapeSerie.cpython-313.pyc +0 -0
  149. StreamingCommunity/Api/Site/ddlstreamitaly/util/__pycache__/ScrapeSerie.cpython-39.pyc +0 -0
  150. StreamingCommunity/Api/Site/guardaserie/__pycache__/__init__.cpython-313.pyc +0 -0
  151. StreamingCommunity/Api/Site/guardaserie/__pycache__/__init__.cpython-39.pyc +0 -0
  152. StreamingCommunity/Api/Site/guardaserie/__pycache__/costant.cpython-313.pyc +0 -0
  153. StreamingCommunity/Api/Site/guardaserie/__pycache__/costant.cpython-39.pyc +0 -0
  154. StreamingCommunity/Api/Site/guardaserie/__pycache__/series.cpython-313.pyc +0 -0
  155. StreamingCommunity/Api/Site/guardaserie/__pycache__/series.cpython-39.pyc +0 -0
  156. StreamingCommunity/Api/Site/guardaserie/__pycache__/site.cpython-313.pyc +0 -0
  157. StreamingCommunity/Api/Site/guardaserie/__pycache__/site.cpython-39.pyc +0 -0
  158. StreamingCommunity/Api/Site/guardaserie/util/__pycache__/ScrapeSerie.cpython-313.pyc +0 -0
  159. StreamingCommunity/Api/Site/guardaserie/util/__pycache__/ScrapeSerie.cpython-39.pyc +0 -0
  160. StreamingCommunity/Api/Site/ilcorsaronero/__pycache__/__init__.cpython-313.pyc +0 -0
  161. StreamingCommunity/Api/Site/ilcorsaronero/__pycache__/__init__.cpython-39.pyc +0 -0
  162. StreamingCommunity/Api/Site/ilcorsaronero/__pycache__/costant.cpython-313.pyc +0 -0
  163. StreamingCommunity/Api/Site/ilcorsaronero/__pycache__/costant.cpython-39.pyc +0 -0
  164. StreamingCommunity/Api/Site/ilcorsaronero/__pycache__/site.cpython-313.pyc +0 -0
  165. StreamingCommunity/Api/Site/ilcorsaronero/__pycache__/site.cpython-39.pyc +0 -0
  166. StreamingCommunity/Api/Site/ilcorsaronero/__pycache__/title.cpython-313.pyc +0 -0
  167. StreamingCommunity/Api/Site/ilcorsaronero/__pycache__/title.cpython-39.pyc +0 -0
  168. StreamingCommunity/Api/Site/ilcorsaronero/util/__pycache__/ilCorsarScraper.cpython-313.pyc +0 -0
  169. StreamingCommunity/Api/Site/ilcorsaronero/util/__pycache__/ilCorsarScraper.cpython-39.pyc +0 -0
  170. StreamingCommunity/Api/Site/mostraguarda/__pycache__/__init__.cpython-313.pyc +0 -0
  171. StreamingCommunity/Api/Site/mostraguarda/__pycache__/__init__.cpython-39.pyc +0 -0
  172. StreamingCommunity/Api/Site/mostraguarda/__pycache__/costant.cpython-313.pyc +0 -0
  173. StreamingCommunity/Api/Site/mostraguarda/__pycache__/costant.cpython-39.pyc +0 -0
  174. StreamingCommunity/Api/Site/mostraguarda/__pycache__/film.cpython-313.pyc +0 -0
  175. StreamingCommunity/Api/Site/mostraguarda/__pycache__/film.cpython-39.pyc +0 -0
  176. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/__init__.cpython-313.pyc +0 -0
  177. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/__init__.cpython-39.pyc +0 -0
  178. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/costant.cpython-313.pyc +0 -0
  179. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/costant.cpython-39.pyc +0 -0
  180. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/film.cpython-313.pyc +0 -0
  181. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/film.cpython-39.pyc +0 -0
  182. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/series.cpython-313.pyc +0 -0
  183. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/series.cpython-39.pyc +0 -0
  184. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/site.cpython-313.pyc +0 -0
  185. StreamingCommunity/Api/Site/streamingcommunity/__pycache__/site.cpython-39.pyc +0 -0
  186. StreamingCommunity/Api/Site/streamingcommunity/util/__pycache__/ScrapeSerie.cpython-313.pyc +0 -0
  187. StreamingCommunity/Api/Site/streamingcommunity/util/__pycache__/ScrapeSerie.cpython-39.pyc +0 -0
  188. StreamingCommunity/Api/Template/Class/__pycache__/SearchType.cpython-313.pyc +0 -0
  189. StreamingCommunity/Api/Template/Class/__pycache__/SearchType.cpython-39.pyc +0 -0
  190. StreamingCommunity/Api/Template/Util/__pycache__/__init__.cpython-313.pyc +0 -0
  191. StreamingCommunity/Api/Template/Util/__pycache__/__init__.cpython-39.pyc +0 -0
  192. StreamingCommunity/Api/Template/Util/__pycache__/get_domain.cpython-313.pyc +0 -0
  193. StreamingCommunity/Api/Template/Util/__pycache__/get_domain.cpython-39.pyc +0 -0
  194. StreamingCommunity/Api/Template/Util/__pycache__/manage_ep.cpython-313.pyc +0 -0
  195. StreamingCommunity/Api/Template/Util/__pycache__/manage_ep.cpython-39.pyc +0 -0
  196. StreamingCommunity/Api/Template/Util/__pycache__/recall_search.cpython-313.pyc +0 -0
  197. StreamingCommunity/Api/Template/Util/__pycache__/recall_search.cpython-39.pyc +0 -0
  198. StreamingCommunity/Api/Template/__pycache__/__init__.cpython-313.pyc +0 -0
  199. StreamingCommunity/Api/Template/__pycache__/__init__.cpython-39.pyc +0 -0
  200. StreamingCommunity/Api/Template/__pycache__/site.cpython-313.pyc +0 -0
  201. StreamingCommunity/Api/Template/__pycache__/site.cpython-39.pyc +0 -0
  202. StreamingCommunity/Lib/Downloader/HLS/__pycache__/downloader.cpython-313.pyc +0 -0
  203. StreamingCommunity/Lib/Downloader/HLS/__pycache__/downloader.cpython-39.pyc +0 -0
  204. StreamingCommunity/Lib/Downloader/HLS/__pycache__/proxyes.cpython-313.pyc +0 -0
  205. StreamingCommunity/Lib/Downloader/HLS/__pycache__/proxyes.cpython-39.pyc +0 -0
  206. StreamingCommunity/Lib/Downloader/HLS/__pycache__/segments.cpython-313.pyc +0 -0
  207. StreamingCommunity/Lib/Downloader/HLS/__pycache__/segments.cpython-39.pyc +0 -0
  208. StreamingCommunity/Lib/Downloader/MP4/__pycache__/downloader.cpython-313.pyc +0 -0
  209. StreamingCommunity/Lib/Downloader/MP4/__pycache__/downloader.cpython-39.pyc +0 -0
  210. StreamingCommunity/Lib/Downloader/TOR/__pycache__/downloader.cpython-313.pyc +0 -0
  211. StreamingCommunity/Lib/Downloader/TOR/__pycache__/downloader.cpython-39.pyc +0 -0
  212. StreamingCommunity/Lib/Downloader/__pycache__/__init__.cpython-313.pyc +0 -0
  213. StreamingCommunity/Lib/Downloader/__pycache__/__init__.cpython-39.pyc +0 -0
  214. StreamingCommunity/Lib/FFmpeg/__pycache__/__init__.cpython-313.pyc +0 -0
  215. StreamingCommunity/Lib/FFmpeg/__pycache__/__init__.cpython-39.pyc +0 -0
  216. StreamingCommunity/Lib/FFmpeg/__pycache__/capture.cpython-313.pyc +0 -0
  217. StreamingCommunity/Lib/FFmpeg/__pycache__/capture.cpython-39.pyc +0 -0
  218. StreamingCommunity/Lib/FFmpeg/__pycache__/command.cpython-313.pyc +0 -0
  219. StreamingCommunity/Lib/FFmpeg/__pycache__/command.cpython-39.pyc +0 -0
  220. StreamingCommunity/Lib/FFmpeg/__pycache__/util.cpython-313.pyc +0 -0
  221. StreamingCommunity/Lib/FFmpeg/__pycache__/util.cpython-39.pyc +0 -0
  222. StreamingCommunity/Lib/M3U8/__pycache__/__init__.cpython-313.pyc +0 -0
  223. StreamingCommunity/Lib/M3U8/__pycache__/__init__.cpython-39.pyc +0 -0
  224. StreamingCommunity/Lib/M3U8/__pycache__/decryptor.cpython-313.pyc +0 -0
  225. StreamingCommunity/Lib/M3U8/__pycache__/decryptor.cpython-39.pyc +0 -0
  226. StreamingCommunity/Lib/M3U8/__pycache__/estimator.cpython-313.pyc +0 -0
  227. StreamingCommunity/Lib/M3U8/__pycache__/estimator.cpython-39.pyc +0 -0
  228. StreamingCommunity/Lib/M3U8/__pycache__/parser.cpython-313.pyc +0 -0
  229. StreamingCommunity/Lib/M3U8/__pycache__/parser.cpython-39.pyc +0 -0
  230. StreamingCommunity/Lib/M3U8/__pycache__/url_fixer.cpython-313.pyc +0 -0
  231. StreamingCommunity/Lib/M3U8/__pycache__/url_fixer.cpython-39.pyc +0 -0
  232. StreamingCommunity/Lib/TMBD/__pycache__/__init__.cpython-313.pyc +0 -0
  233. StreamingCommunity/Lib/TMBD/__pycache__/__init__.cpython-39.pyc +0 -0
  234. StreamingCommunity/Lib/TMBD/__pycache__/obj_tmbd.cpython-313.pyc +0 -0
  235. StreamingCommunity/Lib/TMBD/__pycache__/obj_tmbd.cpython-39.pyc +0 -0
  236. StreamingCommunity/Lib/TMBD/__pycache__/tmdb.cpython-313.pyc +0 -0
  237. StreamingCommunity/Lib/TMBD/__pycache__/tmdb.cpython-39.pyc +0 -0
  238. StreamingCommunity/Upload/__pycache__/update.cpython-313.pyc +0 -0
  239. StreamingCommunity/Upload/__pycache__/update.cpython-39.pyc +0 -0
  240. StreamingCommunity/Upload/__pycache__/version.cpython-313.pyc +0 -0
  241. StreamingCommunity/Upload/__pycache__/version.cpython-39.pyc +0 -0
  242. StreamingCommunity/Util/__pycache__/_jsonConfig.cpython-313.pyc +0 -0
  243. StreamingCommunity/Util/__pycache__/_jsonConfig.cpython-39.pyc +0 -0
  244. StreamingCommunity/Util/__pycache__/call_stack.cpython-313.pyc +0 -0
  245. StreamingCommunity/Util/__pycache__/call_stack.cpython-39.pyc +0 -0
  246. StreamingCommunity/Util/__pycache__/color.cpython-313.pyc +0 -0
  247. StreamingCommunity/Util/__pycache__/color.cpython-39.pyc +0 -0
  248. StreamingCommunity/Util/__pycache__/console.cpython-313.pyc +0 -0
  249. StreamingCommunity/Util/__pycache__/console.cpython-39.pyc +0 -0
  250. StreamingCommunity/Util/__pycache__/ffmpeg_installer.cpython-313.pyc +0 -0
  251. StreamingCommunity/Util/__pycache__/ffmpeg_installer.cpython-39.pyc +0 -0
  252. StreamingCommunity/Util/__pycache__/headers.cpython-313.pyc +0 -0
  253. StreamingCommunity/Util/__pycache__/headers.cpython-39.pyc +0 -0
  254. StreamingCommunity/Util/__pycache__/logger.cpython-313.pyc +0 -0
  255. StreamingCommunity/Util/__pycache__/logger.cpython-39.pyc +0 -0
  256. StreamingCommunity/Util/__pycache__/message.cpython-313.pyc +0 -0
  257. StreamingCommunity/Util/__pycache__/message.cpython-39.pyc +0 -0
  258. StreamingCommunity/Util/__pycache__/os.cpython-313.pyc +0 -0
  259. StreamingCommunity/Util/__pycache__/os.cpython-39.pyc +0 -0
  260. StreamingCommunity/Util/__pycache__/table.cpython-313.pyc +0 -0
  261. StreamingCommunity/Util/__pycache__/table.cpython-39.pyc +0 -0
  262. StreamingCommunity/__pycache__/__init__.cpython-313.pyc +0 -0
  263. StreamingCommunity/__pycache__/__init__.cpython-39.pyc +0 -0
  264. StreamingCommunity/__pycache__/run.cpython-313.pyc +0 -0
  265. StreamingCommunity/__pycache__/run.cpython-39.pyc +0 -0
  266. StreamingCommunity-2.5.2.dist-info/RECORD +0 -264
  267. {StreamingCommunity-2.5.2.dist-info → StreamingCommunity-2.5.5.dist-info}/WHEEL +0 -0
  268. {StreamingCommunity-2.5.2.dist-info → StreamingCommunity-2.5.5.dist-info}/top_level.txt +0 -0
@@ -1,296 +1,264 @@
1
- # 31.01.24
2
-
3
- import sys
4
- import time
5
- import logging
6
- import subprocess
7
- from typing import List, Dict
8
-
9
-
10
- # Internal utilities
11
- from StreamingCommunity.Util._jsonConfig import config_manager
12
- from StreamingCommunity.Util.os import os_manager, os_summary, suppress_output
13
- from StreamingCommunity.Util.console import console
14
-
15
-
16
- # Logic class
17
- from .util import need_to_force_to_ts, check_duration_v_a
18
- from .capture import capture_ffmpeg_real_time
19
- from ..M3U8 import M3U8_Codec
20
-
21
-
22
- # Config
23
- DEBUG_MODE = config_manager.get_bool("DEFAULT", "debug")
24
- DEBUG_FFMPEG = "debug" if DEBUG_MODE else "error"
25
- USE_CODEC = config_manager.get_bool("M3U8_CONVERSION", "use_codec")
26
- USE_VCODEC = config_manager.get_bool("M3U8_CONVERSION", "use_vcodec")
27
- USE_ACODEC = config_manager.get_bool("M3U8_CONVERSION", "use_acodec")
28
- USE_BITRATE = config_manager.get_bool("M3U8_CONVERSION", "use_bitrate")
29
- USE_GPU = config_manager.get_bool("M3U8_CONVERSION", "use_gpu")
30
- FFMPEG_DEFAULT_PRESET = config_manager.get("M3U8_CONVERSION", "default_preset")
31
-
32
-
33
- # Variable
34
- TQDM_USE_LARGE_BAR = config_manager.get_int('M3U8_DOWNLOAD', 'tqdm_use_large_bar')
35
- FFMPEG_PATH = os_summary.ffmpeg_path
36
-
37
-
38
- def join_video(video_path: str, out_path: str, codec: M3U8_Codec = None):
39
-
40
- """
41
- Joins single ts video file to mp4
42
-
43
- Parameters:
44
- - video_path (str): The path to the video file.
45
- - out_path (str): The path to save the output file.
46
- - vcodec (str): The video codec to use. Defaults to 'copy'.
47
- - acodec (str): The audio codec to use. Defaults to 'aac'.
48
- - bitrate (str): The bitrate for the audio stream. Defaults to '192k'.
49
- - force_ts (bool): Force video path to be mpegts as input.
50
- """
51
-
52
- if not os_manager.check_file(video_path):
53
- logging.error("Missing input video for ffmpeg conversion.")
54
- sys.exit(0)
55
-
56
- # Start command with locate ffmpeg
57
- ffmpeg_cmd = [FFMPEG_PATH]
58
-
59
- # Enabled the use of gpu
60
- if USE_GPU:
61
- ffmpeg_cmd.extend(['-hwaccel', 'cuda'])
62
-
63
- # Add mpegts to force to detect input file as ts file
64
- if need_to_force_to_ts(video_path):
65
- #console.log("[red]Force input file to 'mpegts'.")
66
- ffmpeg_cmd.extend(['-f', 'mpegts'])
67
- vcodec = "libx264"
68
-
69
- # Insert input video path
70
- ffmpeg_cmd.extend(['-i', video_path])
71
-
72
- # Add output Parameters
73
- if USE_CODEC and codec != None:
74
- if USE_VCODEC:
75
- if codec.video_codec_name:
76
- if not USE_GPU:
77
- ffmpeg_cmd.extend(['-c:v', codec.video_codec_name])
78
- else:
79
- ffmpeg_cmd.extend(['-c:v', 'h264_nvenc'])
80
- else:
81
- console.log("[red]Cant find vcodec for 'join_audios'")
82
- else:
83
- if USE_GPU:
84
- ffmpeg_cmd.extend(['-c:v', 'h264_nvenc'])
85
-
86
-
87
- if USE_ACODEC:
88
- if codec.audio_codec_name:
89
- ffmpeg_cmd.extend(['-c:a', codec.audio_codec_name])
90
- else:
91
- console.log("[red]Cant find acodec for 'join_audios'")
92
-
93
- if USE_BITRATE:
94
- ffmpeg_cmd.extend(['-b:v', f'{codec.video_bitrate // 1000}k'])
95
- ffmpeg_cmd.extend(['-b:a', f'{codec.audio_bitrate // 1000}k'])
96
-
97
- else:
98
- ffmpeg_cmd.extend(['-c', 'copy'])
99
-
100
- # Ultrafast preset always or fast for gpu
101
- if not USE_GPU:
102
- ffmpeg_cmd.extend(['-preset', FFMPEG_DEFAULT_PRESET])
103
- else:
104
- ffmpeg_cmd.extend(['-preset', 'fast'])
105
-
106
- # Overwrite
107
- ffmpeg_cmd += [out_path, "-y"]
108
-
109
- # Run join
110
- if DEBUG_MODE:
111
- subprocess.run(ffmpeg_cmd, check=True)
112
- else:
113
-
114
- if TQDM_USE_LARGE_BAR:
115
- capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join video")
116
- print()
117
-
118
- else:
119
- console.log(f"[purple]FFmpeg [white][[cyan]Join video[white]] ...")
120
- with suppress_output():
121
- capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join video")
122
- print()
123
-
124
- time.sleep(0.5)
125
- if not os_manager.check_file(out_path):
126
- logging.error("Missing output video for ffmpeg conversion video.")
127
- sys.exit(0)
128
-
129
-
130
- def join_audios(video_path: str, audio_tracks: List[Dict[str, str]], out_path: str, codec: M3U8_Codec = None):
131
- """
132
- Joins audio tracks with a video file using FFmpeg.
133
-
134
- Parameters:
135
- - video_path (str): The path to the video file.
136
- - audio_tracks (list[dict[str, str]]): A list of dictionaries containing information about audio tracks.
137
- Each dictionary should contain the 'path' key with the path to the audio file.
138
- - out_path (str): The path to save the output file.
139
- """
140
-
141
- if not os_manager.check_file(video_path):
142
- logging.error("Missing input video for ffmpeg conversion.")
143
- sys.exit(0)
144
-
145
- video_audio_same_duration = check_duration_v_a(video_path, audio_tracks[0].get('path'))
146
-
147
- # Start command with locate ffmpeg
148
- ffmpeg_cmd = [FFMPEG_PATH]
149
-
150
- # Enabled the use of gpu
151
- if USE_GPU:
152
- ffmpeg_cmd.extend(['-hwaccel', 'cuda'])
153
-
154
- # Insert input video path
155
- ffmpeg_cmd.extend(['-i', video_path])
156
-
157
- # Add audio tracks as input
158
- for i, audio_track in enumerate(audio_tracks):
159
- if os_manager.check_file(audio_track.get('path')):
160
- ffmpeg_cmd.extend(['-i', audio_track.get('path')])
161
- else:
162
- logging.error(f"Skip audio join: {audio_track.get('path')} dont exist")
163
-
164
- # Map the video and audio streams
165
- ffmpeg_cmd.append('-map')
166
- ffmpeg_cmd.append('0:v') # Map video stream from the first input (video_path)
167
-
168
- for i in range(1, len(audio_tracks) + 1):
169
- ffmpeg_cmd.append('-map')
170
- ffmpeg_cmd.append(f'{i}:a') # Map audio streams from subsequent inputs
171
-
172
- # Add output Parameters
173
- if USE_CODEC:
174
- if USE_VCODEC:
175
- if codec.video_codec_name:
176
- if not USE_GPU:
177
- ffmpeg_cmd.extend(['-c:v', codec.video_codec_name])
178
- else:
179
- ffmpeg_cmd.extend(['-c:v', 'h264_nvenc'])
180
- else:
181
- console.log("[red]Cant find vcodec for 'join_audios'")
182
- else:
183
- if USE_GPU:
184
- ffmpeg_cmd.extend(['-c:v', 'h264_nvenc'])
185
-
186
- if USE_ACODEC:
187
- if codec.audio_codec_name:
188
- ffmpeg_cmd.extend(['-c:a', codec.audio_codec_name])
189
- else:
190
- console.log("[red]Cant find acodec for 'join_audios'")
191
-
192
- if USE_BITRATE:
193
- ffmpeg_cmd.extend(['-b:v', f'{codec.video_bitrate // 1000}k'])
194
- ffmpeg_cmd.extend(['-b:a', f'{codec.audio_bitrate // 1000}k'])
195
-
196
- else:
197
- ffmpeg_cmd.extend(['-c', 'copy'])
198
-
199
- # Ultrafast preset always or fast for gpu
200
- if not USE_GPU:
201
- ffmpeg_cmd.extend(['-preset', FFMPEG_DEFAULT_PRESET])
202
- else:
203
- ffmpeg_cmd.extend(['-preset', 'fast'])
204
-
205
- # Use shortest input path for video and audios
206
- if not video_audio_same_duration:
207
- logging.info("[red]Use shortest input.")
208
- ffmpeg_cmd.extend(['-shortest', '-strict', 'experimental'])
209
-
210
- # Overwrite
211
- ffmpeg_cmd += [out_path, "-y"]
212
-
213
- # Run join
214
- if DEBUG_MODE:
215
- subprocess.run(ffmpeg_cmd, check=True)
216
- else:
217
-
218
- if TQDM_USE_LARGE_BAR:
219
- capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join audio")
220
- print()
221
-
222
- else:
223
- console.log(f"[purple]FFmpeg [white][[cyan]Join audio[white]] ...")
224
- with suppress_output():
225
- capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join audio")
226
- print()
227
-
228
- time.sleep(0.5)
229
- if not os_manager.check_file(out_path):
230
- logging.error("Missing output video for ffmpeg conversion audio.")
231
- sys.exit(0)
232
-
233
-
234
- def join_subtitle(video_path: str, subtitles_list: List[Dict[str, str]], out_path: str):
235
- """
236
- Joins subtitles with a video file using FFmpeg.
237
-
238
- Parameters:
239
- - video (str): The path to the video file.
240
- - subtitles_list (list[dict[str, str]]): A list of dictionaries containing information about subtitles.
241
- Each dictionary should contain the 'path' key with the path to the subtitle file and the 'name' key with the name of the subtitle.
242
- - out_path (str): The path to save the output file.
243
- """
244
-
245
- if not os_manager.check_file(video_path):
246
- logging.error("Missing input video for ffmpeg conversion.")
247
- sys.exit(0)
248
-
249
- # Start command with locate ffmpeg
250
- ffmpeg_cmd = [FFMPEG_PATH, "-i", video_path]
251
-
252
- # Add subtitle input files first
253
- for subtitle in subtitles_list:
254
- if os_manager.check_file(subtitle.get('path')):
255
- ffmpeg_cmd += ["-i", subtitle['path']]
256
- else:
257
- logging.error(f"Skip subtitle join: {subtitle.get('path')} doesn't exist")
258
-
259
- # Add maps for video and audio streams
260
- ffmpeg_cmd += ["-map", "0:v", "-map", "0:a"]
261
-
262
- # Add subtitle maps and metadata
263
- for idx, subtitle in enumerate(subtitles_list):
264
- ffmpeg_cmd += ["-map", f"{idx + 1}:s"]
265
- ffmpeg_cmd += ["-metadata:s:s:{}".format(idx), "title={}".format(subtitle['language'])]
266
-
267
- # Add output Parameters
268
- if USE_CODEC:
269
- ffmpeg_cmd.extend(['-c:v', 'copy', '-c:a', 'copy', '-c:s', 'mov_text'])
270
- else:
271
- ffmpeg_cmd.extend(['-c', 'copy', '-c:s', 'mov_text'])
272
-
273
- # Overwrite
274
- ffmpeg_cmd += [out_path, "-y"]
275
- logging.info(f"FFmpeg command: {ffmpeg_cmd}")
276
-
277
-
278
- # Run join
279
- if DEBUG_MODE:
280
- subprocess.run(ffmpeg_cmd, check=True)
281
- else:
282
-
283
- if TQDM_USE_LARGE_BAR:
284
- capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join subtitle")
285
- print()
286
-
287
- else:
288
- console.log(f"[purple]FFmpeg [white][[cyan]Join subtitle[white]] ...")
289
- with suppress_output():
290
- capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join subtitle")
291
- print()
292
-
293
- time.sleep(0.5)
294
- if not os_manager.check_file(out_path):
295
- logging.error("Missing output video for ffmpeg conversion subtitle.")
296
- sys.exit(0)
1
+ # 31.01.24
2
+
3
+ import sys
4
+ import logging
5
+ import subprocess
6
+ from typing import List, Dict
7
+
8
+
9
+ # Internal utilities
10
+ from StreamingCommunity.Util._jsonConfig import config_manager
11
+ from StreamingCommunity.Util.os import os_manager, os_summary, suppress_output
12
+ from StreamingCommunity.Util.console import console
13
+
14
+
15
+ # Logic class
16
+ from .util import need_to_force_to_ts, check_duration_v_a
17
+ from .capture import capture_ffmpeg_real_time
18
+ from ..M3U8 import M3U8_Codec
19
+
20
+
21
+ # Config
22
+ DEBUG_MODE = config_manager.get_bool("DEFAULT", "debug")
23
+ DEBUG_FFMPEG = "debug" if DEBUG_MODE else "error"
24
+ USE_CODEC = config_manager.get_bool("M3U8_CONVERSION", "use_codec")
25
+ USE_VCODEC = config_manager.get_bool("M3U8_CONVERSION", "use_vcodec")
26
+ USE_ACODEC = config_manager.get_bool("M3U8_CONVERSION", "use_acodec")
27
+ USE_BITRATE = config_manager.get_bool("M3U8_CONVERSION", "use_bitrate")
28
+ USE_GPU = config_manager.get_bool("M3U8_CONVERSION", "use_gpu")
29
+ FFMPEG_DEFAULT_PRESET = config_manager.get("M3U8_CONVERSION", "default_preset")
30
+
31
+
32
+ # Variable
33
+ USE_LARGE_BAR = not ("android" in sys.platform or "ios" in sys.platform)
34
+ FFMPEG_PATH = os_summary.ffmpeg_path
35
+
36
+
37
+ def join_video(video_path: str, out_path: str, codec: M3U8_Codec = None):
38
+ """
39
+ Joins single ts video file to mp4
40
+
41
+ Parameters:
42
+ - video_path (str): The path to the video file.
43
+ - out_path (str): The path to save the output file.
44
+ - codec (M3U8_Codec): The video codec to use. Defaults to 'copy'.
45
+ """
46
+ ffmpeg_cmd = [FFMPEG_PATH]
47
+
48
+ # Enabled the use of gpu
49
+ if USE_GPU:
50
+ ffmpeg_cmd.extend(['-hwaccel', 'cuda'])
51
+
52
+ # Add mpegts to force to detect input file as ts file
53
+ if need_to_force_to_ts(video_path):
54
+ #console.log("[red]Force input file to 'mpegts'.")
55
+ ffmpeg_cmd.extend(['-f', 'mpegts'])
56
+ vcodec = "libx264"
57
+
58
+ # Insert input video path
59
+ ffmpeg_cmd.extend(['-i', video_path])
60
+
61
+ # Add output Parameters
62
+ if USE_CODEC and codec != None:
63
+ if USE_VCODEC:
64
+ if codec.video_codec_name:
65
+ if not USE_GPU:
66
+ ffmpeg_cmd.extend(['-c:v', codec.video_codec_name])
67
+ else:
68
+ ffmpeg_cmd.extend(['-c:v', 'h264_nvenc'])
69
+ else:
70
+ console.log("[red]Cant find vcodec for 'join_audios'")
71
+ else:
72
+ if USE_GPU:
73
+ ffmpeg_cmd.extend(['-c:v', 'h264_nvenc'])
74
+
75
+
76
+ if USE_ACODEC:
77
+ if codec.audio_codec_name:
78
+ ffmpeg_cmd.extend(['-c:a', codec.audio_codec_name])
79
+ else:
80
+ console.log("[red]Cant find acodec for 'join_audios'")
81
+
82
+ if USE_BITRATE:
83
+ ffmpeg_cmd.extend(['-b:v', f'{codec.video_bitrate // 1000}k'])
84
+ ffmpeg_cmd.extend(['-b:a', f'{codec.audio_bitrate // 1000}k'])
85
+
86
+ else:
87
+ ffmpeg_cmd.extend(['-c', 'copy'])
88
+
89
+ # Ultrafast preset always or fast for gpu
90
+ if not USE_GPU:
91
+ ffmpeg_cmd.extend(['-preset', FFMPEG_DEFAULT_PRESET])
92
+ else:
93
+ ffmpeg_cmd.extend(['-preset', 'fast'])
94
+
95
+ # Overwrite
96
+ ffmpeg_cmd += [out_path, "-y"]
97
+
98
+ # Run join
99
+ if DEBUG_MODE:
100
+ subprocess.run(ffmpeg_cmd, check=True)
101
+ else:
102
+
103
+ if USE_LARGE_BAR:
104
+ capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join video")
105
+ print()
106
+
107
+ else:
108
+ console.log(f"[purple]FFmpeg [white][[cyan]Join video[white]] ...")
109
+ with suppress_output():
110
+ capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join video")
111
+ print()
112
+
113
+ return out_path
114
+
115
+
116
+ def join_audios(video_path: str, audio_tracks: List[Dict[str, str]], out_path: str, codec: M3U8_Codec = None):
117
+ """
118
+ Joins audio tracks with a video file using FFmpeg.
119
+
120
+ Parameters:
121
+ - video_path (str): The path to the video file.
122
+ - audio_tracks (list[dict[str, str]]): A list of dictionaries containing information about audio tracks.
123
+ Each dictionary should contain the 'path' key with the path to the audio file.
124
+ - out_path (str): The path to save the output file.
125
+ """
126
+ video_audio_same_duration = check_duration_v_a(video_path, audio_tracks[0].get('path'))
127
+
128
+ # Start command with locate ffmpeg
129
+ ffmpeg_cmd = [FFMPEG_PATH]
130
+
131
+ # Enabled the use of gpu
132
+ if USE_GPU:
133
+ ffmpeg_cmd.extend(['-hwaccel', 'cuda'])
134
+
135
+ # Insert input video path
136
+ ffmpeg_cmd.extend(['-i', video_path])
137
+
138
+ # Add audio tracks as input
139
+ for i, audio_track in enumerate(audio_tracks):
140
+ if os_manager.check_file(audio_track.get('path')):
141
+ ffmpeg_cmd.extend(['-i', audio_track.get('path')])
142
+ else:
143
+ logging.error(f"Skip audio join: {audio_track.get('path')} dont exist")
144
+
145
+ # Map the video and audio streams
146
+ ffmpeg_cmd.append('-map')
147
+ ffmpeg_cmd.append('0:v') # Map video stream from the first input (video_path)
148
+
149
+ for i in range(1, len(audio_tracks) + 1):
150
+ ffmpeg_cmd.append('-map')
151
+ ffmpeg_cmd.append(f'{i}:a') # Map audio streams from subsequent inputs
152
+
153
+ # Add output Parameters
154
+ if USE_CODEC:
155
+ if USE_VCODEC:
156
+ if codec.video_codec_name:
157
+ if not USE_GPU:
158
+ ffmpeg_cmd.extend(['-c:v', codec.video_codec_name])
159
+ else:
160
+ ffmpeg_cmd.extend(['-c:v', 'h264_nvenc'])
161
+ else:
162
+ console.log("[red]Cant find vcodec for 'join_audios'")
163
+ else:
164
+ if USE_GPU:
165
+ ffmpeg_cmd.extend(['-c:v', 'h264_nvenc'])
166
+
167
+ if USE_ACODEC:
168
+ if codec.audio_codec_name:
169
+ ffmpeg_cmd.extend(['-c:a', codec.audio_codec_name])
170
+ else:
171
+ console.log("[red]Cant find acodec for 'join_audios'")
172
+
173
+ if USE_BITRATE:
174
+ ffmpeg_cmd.extend(['-b:v', f'{codec.video_bitrate // 1000}k'])
175
+ ffmpeg_cmd.extend(['-b:a', f'{codec.audio_bitrate // 1000}k'])
176
+
177
+ else:
178
+ ffmpeg_cmd.extend(['-c', 'copy'])
179
+
180
+ # Ultrafast preset always or fast for gpu
181
+ if not USE_GPU:
182
+ ffmpeg_cmd.extend(['-preset', FFMPEG_DEFAULT_PRESET])
183
+ else:
184
+ ffmpeg_cmd.extend(['-preset', 'fast'])
185
+
186
+ # Use shortest input path for video and audios
187
+ if not video_audio_same_duration:
188
+ logging.info("[red]Use shortest input.")
189
+ ffmpeg_cmd.extend(['-shortest', '-strict', 'experimental'])
190
+
191
+ # Overwrite
192
+ ffmpeg_cmd += [out_path, "-y"]
193
+
194
+ # Run join
195
+ if DEBUG_MODE:
196
+ subprocess.run(ffmpeg_cmd, check=True)
197
+ else:
198
+
199
+ if USE_LARGE_BAR:
200
+ capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join audio")
201
+ print()
202
+
203
+ else:
204
+ console.log(f"[purple]FFmpeg [white][[cyan]Join audio[white]] ...")
205
+ with suppress_output():
206
+ capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join audio")
207
+ print()
208
+
209
+ return out_path
210
+
211
+
212
+ def join_subtitle(video_path: str, subtitles_list: List[Dict[str, str]], out_path: str):
213
+ """
214
+ Joins subtitles with a video file using FFmpeg.
215
+
216
+ Parameters:
217
+ - video (str): The path to the video file.
218
+ - subtitles_list (list[dict[str, str]]): A list of dictionaries containing information about subtitles.
219
+ Each dictionary should contain the 'path' key with the path to the subtitle file and the 'name' key with the name of the subtitle.
220
+ - out_path (str): The path to save the output file.
221
+ """
222
+ ffmpeg_cmd = [FFMPEG_PATH, "-i", video_path]
223
+
224
+ # Add subtitle input files first
225
+ for subtitle in subtitles_list:
226
+ if os_manager.check_file(subtitle.get('path')):
227
+ ffmpeg_cmd += ["-i", subtitle['path']]
228
+ else:
229
+ logging.error(f"Skip subtitle join: {subtitle.get('path')} doesn't exist")
230
+
231
+ # Add maps for video and audio streams
232
+ ffmpeg_cmd += ["-map", "0:v", "-map", "0:a"]
233
+
234
+ # Add subtitle maps and metadata
235
+ for idx, subtitle in enumerate(subtitles_list):
236
+ ffmpeg_cmd += ["-map", f"{idx + 1}:s"]
237
+ ffmpeg_cmd += ["-metadata:s:s:{}".format(idx), "title={}".format(subtitle['language'])]
238
+
239
+ # Add output Parameters
240
+ if USE_CODEC:
241
+ ffmpeg_cmd.extend(['-c:v', 'copy', '-c:a', 'copy', '-c:s', 'mov_text'])
242
+ else:
243
+ ffmpeg_cmd.extend(['-c', 'copy', '-c:s', 'mov_text'])
244
+
245
+ # Overwrite
246
+ ffmpeg_cmd += [out_path, "-y"]
247
+ logging.info(f"FFmpeg command: {ffmpeg_cmd}")
248
+
249
+ # Run join
250
+ if DEBUG_MODE:
251
+ subprocess.run(ffmpeg_cmd, check=True)
252
+ else:
253
+
254
+ if USE_LARGE_BAR:
255
+ capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join subtitle")
256
+ print()
257
+
258
+ else:
259
+ console.log(f"[purple]FFmpeg [white][[cyan]Join subtitle[white]] ...")
260
+ with suppress_output():
261
+ capture_ffmpeg_real_time(ffmpeg_cmd, "[cyan]Join subtitle")
262
+ print()
263
+
264
+ return out_path