Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

plugins.tf1: Permission insuffisante #5379

Closed
4 tasks done
campones opened this issue Jun 13, 2023 · 42 comments · Fixed by #5983
Closed
4 tasks done

plugins.tf1: Permission insuffisante #5379

campones opened this issue Jun 13, 2023 · 42 comments · Fixed by #5983
Labels
plugin issue A Plugin does not work correctly restriction: account needed

Comments

@campones
Copy link

Checklist

Streamlink version

Latest stable release

Description

Hi
Not sure exactly what means "permissions insuffisante" but sounds like something changed. Only LCI is still working

Debug log

/usr/local/bin/streamlink --loglevel debug "http://www.tf1.fr/tmc/direct" best                                                                                                         [cli][info] streamlink is running as root! Be careful!
[cli][debug] OS:         Linux-5.15.0-73-generic-x86_64-with-glibc2.29
[cli][debug] Python:     3.8.10
[cli][debug] Streamlink: 5.5.1
[cli][debug] Dependencies:
[cli][debug]  certifi: 2019.11.28
[cli][debug]  isodate: 0.6.0
[cli][debug]  lxml: 4.8.0
[cli][debug]  pycountry: 22.3.5
[cli][debug]  pycryptodome: 3.9.9
[cli][debug]  PySocks: 1.7.1
[cli][debug]  requests: 2.27.1
[cli][debug]  urllib3: 1.26.13
[cli][debug]  websocket-client: 1.3.2
[cli][debug] Arguments:
[cli][debug]  url=http://www.tf1.fr/tmc/direct
[cli][debug]  stream=['best']
[cli][debug]  --loglevel=debug
[cli][info] Found matching plugin tf1 for URL http://www.tf1.fr/tmc/direct
[plugins.tf1][debug] Found channel tmc (L_TMC)
[plugins.tf1][error] Permission insuffisante
error: No playable streams found on this URL: http://www.tf1.fr/tmc/direct
@campones campones added the plugin issue A Plugin does not work correctly label Jun 13, 2023
@campones campones changed the title Plugin TF1 group Plugin TF1 - Permission Insuffisante Jun 14, 2023
@bastimeyer bastimeyer changed the title Plugin TF1 - Permission Insuffisante plugins.tf1: Permission insuffisante Jun 14, 2023
@novazur972
Copy link

confirmed for me.
probably related to the creation of the subscription to tf1max (none free)

@campones
Copy link
Author

campones commented Jun 17, 2023

I dont think so because apparently tf1 max's purpose is to propose an ad-free streaming experience as well as HD streaming.
I could watch just fine on their site with just a free login

@BellezaEmporium
Copy link
Contributor

It's not because of this. It now requires a JWT token in order to get access to their metadata. This token can be found by doing a single request to their API on post login, to this website : https://www.tf1.fr/token/gigya/web. It'll need a token based on the Gigya signature (UIDSignature on Gigya login -> https://compte.tf1.fr/accounts.login).

@campones
Copy link
Author

It's not because of this. It now requires a JWT token in order to get access to their metadata. This token can be found by doing a single request to their API on post login, to this website : https://www.tf1.fr/token/gigya/web. It'll need a token based on the Gigya signature (UIDSignature on Gigya login -> https://compte.tf1.fr/accounts.login).

Do you think you would know how to update the current plugin ?

@BellezaEmporium
Copy link
Contributor

BellezaEmporium commented Jun 26, 2023

It's not because of this. It now requires a JWT token in order to get access to their metadata. This token can be found by doing a single request to their API on post login, to this website : https://www.tf1.fr/token/gigya/web. It'll need a token based on the Gigya signature (UIDSignature on Gigya login -> https://compte.tf1.fr/accounts.login).

Do you think you would know how to update the current plugin ?

It would need a POST to https://compte.tf1.fr/accounts.login

loginID= *email* &password= *password* &sessionExpiration=31536000&targetEnv=jssdk&include=identities-all%2Cdata%2Cprofile%2Cpreferences%2C&includeUserInfo=true&loginMode=standard&lang=fr&APIKey=3_hWgJdARhz_7l1oOp3a8BDLoR9cuWZpUaKG4aqF7gum9_iK3uTZ2VlDBl8ANf8FVk&sdk=js_latest&authMode=cookie&pageURL=https%3A%2F%2Fwww.tf1.fr%2F&sdkBuild=13987&format=json

You then grab the UIDSignature and the UID from the Gigya response (either from the accounts login, either from the userInfo, UID + UIDSignature).

You then POST to https://www.tf1.fr/token/gigya/web, in order for this request to work you will also need to create a timestamp in EPOCH/UNIX format (something like 1687780538)

{"uid":" *UID* ","signature":" *UIDSignature* ","timestamp":,"consent_ids":["1","2","3","4","10001","10003","10005","10007","10013","10015","10017","10019","10009","10011","13002","13001","10004","10014","10016","10018","10020","10010","10012","10006","10008"]

You grab the "token" from the JSON answer.

After that, you can do a GET request to https://mediainfo.tf1.fr/mediainfocombo/L_TF1?pver=5010000&context=MYTF1&topDomain=unknown&platform=web&device=desktop&os=windows&osVersion=10.0&playerVersion=5.10.0&productName=mytf1&productVersion=2.59.2&browser=firefox&browserVersion=114 with a specific header Authorization : Bearer token.

Answer will be in "delivery" -> "url"

@campones
Copy link
Author

if you fork the current plugin, let me know, thanks :)

@pokemaster974
Copy link

pokemaster974 commented Jul 1, 2023

You grab the "token" from the JSON answer.

After that, you can do a GET request to https://mediainfo.tf1.fr/mediainfocombo/L_TF1?pver=5010000&context=MYTF1&topDomain=unknown&platform=web&device=desktop&os=windows&osVersion=10.0&playerVersion=5.10.0&productName=mytf1&productVersion=2.59.2&browser=firefox&browserVersion=114 with a specific header Authorization : Bearer token.

Answer will be in "delivery" -> "url"

Hi @BellezaEmporium I try your advice, got the token and got the url into delivery.
But if I add it into a stremalink command to record the direct, I will receive an output with always the same video which is not the direct but a show which have been aired 3 or 4 hours before.

This is the log :

D:\youtube-dl\TF1>streamlink --output "TF1-{time:%Y-%m-%d_%H-%M-%S}.ts" --hls-duration 00:01:00 --loglevel debug https://live-tf1-das.cdn-0.diff.tf1.fr/[Redacted]/out/v1/dfe36f90964947129902b842b83e65b4/index.mpd best
[cli][debug] OS:         Windows 10
[cli][debug] Python:     3.11.3
[cli][debug] Streamlink: 5.5.1
[cli][debug] Dependencies:
[cli][debug]  certifi: 2023.5.7
[cli][debug]  isodate: 0.6.1
[cli][debug]  lxml: 4.9.2
[cli][debug]  pycountry: 22.3.5
[cli][debug]  pycryptodome: 3.18.0
[cli][debug]  PySocks: 1.7.1
[cli][debug]  requests: 2.31.0
[cli][debug]  urllib3: 2.0.2
[cli][debug]  websocket-client: 1.5.2
[cli][debug] Arguments:
[cli][debug]  url=https://live-tf1-das.cdn-0.diff.tf1.fr/[Redacted]/out/v1/dfe36f90964947129902b842b83e65b4/index.mpd
[cli][debug]  stream=['best']
[cli][debug]  --loglevel=debug
[cli][debug]  --player="C:\Program Files\Sans installation\mpv\mpv.exe"
[cli][debug]  --output=TF1-{time:%Y-%m-%d_%H-%M-%S}.ts
[cli][debug]  --hls-duration=60
[cli][debug]  --ffmpeg-ffmpeg=C:\Program Files\Streamlink\ffmpeg\ffmpeg.exe
[cli][info] Found matching plugin dash for URL https://live-tf1-das.cdn-0.diff.tf1.fr/[Redacted]/out/v1/dfe36f90964947129902b842b83e65b4/index.mpd
[plugins.dash][debug] URL=https://live-tf1-das.cdn-0.diff.tf1.fr/[Redacted]/out/v1/dfe36f90964947129902b842b83e65b4/index.mpd; params={}
[utils.l10n][debug] Language code: fr_FR
[stream.dash][debug] Available languages for DASH audio streams: mul, sme, fra (using: mul)
[cli][info] Available streams: 234p (worst), 360p, 576p_alt, 576p, 720p (best)
[cli][info] Opening stream: 720p (dash)
[cli][info] Writing output to
D:\youtube-dl\TF1\TF1-2023-07-01_19-36-51.ts
[cli][debug] Checking file output
[stream.dash][debug] Opening DASH reader for: ('1474100', '1485523442', '1') - video/mp4
[stream.dash][debug] Opening DASH reader for: ('1474100', '1299661462', '6') - audio/mp4
[stream.dash][debug] video/mp4 segment initialization: downloading (2023-07-01T13:19:14.375000Z / 2023-07-01T17:36:51.113869Z)
[stream.dash_manifest][debug] Generating segment timeline for dynamic playlist: ('1474100', '1485523442', '1')
[stream.dash][debug] audio/mp4 segment initialization: downloading (2023-07-01T13:19:14.375000Z / 2023-07-01T17:36:51.116867Z)
[stream.dash_manifest][debug] Generating segment timeline for dynamic playlist: ('1474100', '1299661462', '6')
[stream.dash][debug] Reloading manifest ('1474100', '1485523442', '1')
[stream.dash][debug] Reloading manifest ('1474100', '1299661462', '6')
[stream.dash][debug] video/mp4 segment 1474256: downloading (2023-07-01T17:36:32.720000Z / 2023-07-01T17:36:51.141859Z)
[stream.dash][debug] video/mp4 segment initialization: completed
[stream.ffmpegmux][debug] ffmpeg version n6.0-3-g0e11aafb08-20230310 Copyright (c) 2000-2023 the FFmpeg developers
[stream.ffmpegmux][debug]  built with gcc 12.2.0 (crosstool-NG 1.25.0.90_cf9beb1)
[stream.ffmpegmux][debug]  configuration: --prefix=/ffbuild/prefix --pkg-config-flags=--static --pkg-config=pkg-config --cross-prefix=x86_64-w64-mingw32- --arch=x86_64 --target-os=mingw32 --enable-gpl --enable-version3 --disable-debug --disable-w32threads --enable-pthreads --enable-iconv --enable-libxml2 --enable-zlib --enable-libfreetype --enable-libfribidi --enable-gmp --enable-lzma --enable-fontconfig --enable-libvorbis --enable-opencl --disable-libpulse --enable-libvmaf --disable-libxcb --disable-xlib --enable-amf --enable-libaom --enable-libaribb24 --enable-avisynth --enable-chromaprint --enable-libdav1d --enable-libdavs2 --disable-libfdk-aac --enable-ffnvcodec --enable-cuda-llvm --enable-frei0r --enable-libgme --enable-libkvazaar --enable-libass --enable-libbluray --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librist --enable-libssh --enable-libtheora --enable-libvpx --enable-libwebp --enable-lv2 --disable-libmfx --enable-libvpl --enable-openal --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopenmpt --enable-librav1e --enable-librubberband --enable-schannel --enable-sdl2 --enable-libsoxr --enable-libsrt --enable-libsvtav1 --enable-libtwolame --enable-libuavs3d --disable-libdrm --disable-vaapi --enable-libvidstab --enable-vulkan --enable-libshaderc --enable-libplacebo --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libzimg --enable-libzvbi --extra-cflags=-DLIBTWOLAME_STATIC --extra-cxxflags= --extra-ldflags=-pthread --extra-ldexeflags= --extra-libs=-lgomp --extra-version=20230310
[stream.ffmpegmux][debug]  libavutil      58.  2.100 / 58.  2.100
[stream.ffmpegmux][debug]  libavcodec     60.  3.100 / 60.  3.100
[stream.ffmpegmux][debug]  libavformat    60.  3.100 / 60.  3.100
[stream.ffmpegmux][debug]  libavdevice    60.  1.100 / 60.  1.100
[stream.ffmpegmux][debug]  libavfilter     9.  3.100 /  9.  3.100
[stream.ffmpegmux][debug]  libswscale      7.  1.100 /  7.  1.100
[stream.ffmpegmux][debug]  libswresample   4. 10.100 /  4. 10.100
[stream.ffmpegmux][debug]  libpostproc    57.  1.100 / 57.  1.100
[utils.named_pipe][info] Creating pipe streamlinkpipe-17768-1-4393
[utils.named_pipe][info] Creating pipe streamlinkpipe-17768-2-523
[stream.ffmpegmux][debug] ffmpeg command: C:\Program Files\Streamlink\ffmpeg\ffmpeg.exe -nostats -y -i \\.\pipe\streamlinkpipe-17768-1-4393 -i \\.\pipe\streamlinkpipe-17768-2-523 -c:v copy -c:a copy -copyts -f matroska pipe:1
[stream.ffmpegmux][debug] Starting copy to pipe: \\.\pipe\streamlinkpipe-17768-1-4393
[stream.ffmpegmux][debug] Starting copy to pipe: \\.\pipe\streamlinkpipe-17768-2-523
[cli][debug] Pre-buffering 8192 bytes
[stream.dash][debug] audio/mp4 segment 1474256: downloading (2023-07-01T17:36:32.720000Z / 2023-07-01T17:36:51.207836Z)
[stream.dash][debug] audio/mp4 segment initialization: completed
[stream.dash][debug] audio/mp4 segment 1474257: downloading (2023-07-01T17:36:40.720000Z / 2023-07-01T17:36:51.338794Z)
[stream.dash][debug] audio/mp4 segment 1474256: completed
[stream.dash][debug] video/mp4 segment 1474257: downloading (2023-07-01T17:36:40.720000Z / 2023-07-01T17:36:51.340793Z)
[stream.dash][debug] video/mp4 segment 1474256: completed
[stream.dash][debug] audio/mp4 segment 1474258: downloading (2023-07-01T17:36:48.720000Z / 2023-07-01T17:36:51.509740Z)
[stream.dash][debug] audio/mp4 segment 1474257: completed
[stream.dash][debug] audio/mp4 segment 1474259: downloading (2023-07-01T17:36:50.000000Z / 2023-07-01T17:36:51.535731Z)
[stream.dash][debug] audio/mp4 segment 1474258: completed
[cli][debug] Writing stream to output
[stream.dash][debug] audio/mp4 segment 1474259: completed
[stream.dash][debug] video/mp4 segment 1474258: downloading (2023-07-01T17:36:48.720000Z / 2023-07-01T17:36:51.699216Z)
[stream.dash][debug] video/mp4 segment 1474257: completed
[download] Written 5.02 MiB to TF1-2023-07-01_19-36-51.ts (0s)                                                                                                                                                                                                                                                                                                                            [stream.dash][debug] video/mp4 segment 1474259: downloading (2023-07-01T17:36:50.000000Z / 2023-07-01T17:36:51.894159Z)
[stream.dash][debug] video/mp4 segment 1474258: completed
[stream.dash][debug] video/mp4 segment 1474259: completed
[download] Written 7.99 MiB to TF1-2023-07-01_19-36-51.ts (1m00s @ 0 bytes/s)                                                                                                                                                                                                                                                                                                             [stream.ffmpegmux][error] Error while reading from substream: Read timeout
[stream.ffmpegmux][error] Error while reading from substream: Read timeout

[stream.ffmpegmux][debug] Closing ffmpeg thread
[stream.segmented][debug] Closing worker thread
[stream.segmented][debug] Closing writer thread
[stream.segmented][debug] Closing worker thread
[stream.segmented][debug] Closing writer thread
[stream.segmented][debug] Closing writer thread
[stream.segmented][debug] Closing writer thread
[stream.ffmpegmux][debug] Closed all the substreams
[cli][info] Stream ended
[cli][info] Closing currently open stream...

Do you know what I'm doing wrong ?
My goal was to record 1 minute of the direct (the same which is played into the website).
Regards.

@BellezaEmporium
Copy link
Contributor

I'll have to check as I'm quite unsure about if it's a Streamlink DASH issue or TF1 having the live feed + 4 hours of replay.

@pokemaster974
Copy link

I'll have to check as I'm quite unsure about if it's a Streamlink DASH issue or TF1 having the live feed + 4 hours of replay.

Putting the link into yt-dlp gives me several video tracks, I think streamlink doesn't record the newest one :

D:\youtube-dl>yt-dlp -vF https://live-tf1-das.cdn-0.diff.tf1.fr/[Redacted]/out/v1/dfe36f90964947129902b842b83e65b4/index.mpd
[debug] Command-line config: ['-vF', 'https://live-tf1-das.cdn-0.diff.tf1.fr/[Redacted]/out/v1/dfe36f90964947129902b842b83e65b4/index.mpd']
[debug] Encodings: locale cp1252, fs utf-8, pref cp1252, out utf-8, error utf-8, screen utf-8 
[debug] yt-dlp version stable@2023.06.22 [812cdfa06] (pip) 
[debug] Python 3.11.2 (CPython AMD64 64bit) - Windows-10-10.0.19045-SP0 (OpenSSL 1.1.1s  1 Nov 2022) 
[debug] exe versions: ffmpeg 2023-06-26-git-285c7f6f6b-full_build-www.gyan.dev (setts), ffprobe 2023-06-26-git-285c7f6f6b-full_build-www.gyan.dev 
[debug] Optional libraries: Cryptodome-3.18.0, brotli-1.0.9, certifi-2023.05.07, mutagen-1.46.0, sqlite3-2.6.0, websockets-11.0.3 
[debug] Proxy map: {}
[debug] Loaded 1851 extractors 
[generic] Extracting URL: https://live-tf1-das.cdn-0.diff.tf1.fr/[Redacted]/out/v1/dfe36f90964947129902b842b83e65b4/index.mpd
[generic] index: Downloading webpage 
WARNING: [generic] Falling back on generic information extractor 
[generic] index: Extracting information 
[debug] Identified a DASH manifest 
[debug] Formats sorted by: hasvid, ie_pref, lang, quality, res, fps, hdr:12(7), vcodec:vp9.2(10), channels, acodec, size, br, asr, proto, vext, aext, hasaud, source, id 
[info] Available formats for index: 
ID   EXT RESOLUTION │   TBR PROTO │ VCODEC        VBR ACODEC      ABR ASR MORE INFO 
──────────────────────────────────────────────────────────────────────────────────────────────────── 
6-0  m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-1  m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-2  m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-3  m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-4  m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-5  m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-6  m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-7  m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-8  m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-9  m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-10 m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-11 m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-12 m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-13 m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-14 m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-15 m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-16 m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-17 m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-18 m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
6-19 m4a audio only │   96k dash  │ audio only        mp4a.40.2   96k 48k DASH audio, m4a_dash       
7-0  m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-1  m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-2  m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-3  m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-4  m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-5  m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-6  m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-7  m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-8  m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-9  m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-10 m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-11 m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-12 m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-13 m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-14 m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-15 m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-16 m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-17 m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-18 m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
7-19 m4a audio only │   97k dash  │ audio only        mp4a.40.2   97k 48k [sme] DASH audio, m4a_dash 
8-0  m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-1  m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-2  m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-3  m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-4  m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-5  m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-6  m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-7  m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-8  m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-9  m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-10 m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-11 m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-12 m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-13 m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-14 m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-15 m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-16 m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-17 m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-18 m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
8-19 m4a audio only │  129k dash  │ audio only        mp4a.40.2  129k 48k [fra] DASH audio, m4a_dash 
5-0  mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash       
5-1  mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash       
5-2  mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash       
5-3  mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash       
5-4  mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash       
5-5  mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash       
5-6  mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash       
5-7  mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash
5-8  mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash
5-9  mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash
5-10 mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash
5-11 mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash
5-12 mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash
5-13 mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash
5-14 mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash
5-15 mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash
5-16 mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash
5-17 mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash
5-18 mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash
5-19 mp4 416x234    │  400k dash  │ avc1.42C00D  400k video only          DASH video, mp4_dash
4-0  mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-1  mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-2  mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-3  mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-4  mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-5  mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-6  mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-7  mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-8  mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-9  mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-10 mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-11 mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-12 mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-13 mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-14 mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-15 mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-16 mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-17 mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-18 mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
4-19 mp4 640x360    │  800k dash  │ avc1.42C01E  800k video only          DASH video, mp4_dash
3-0  mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-1  mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-2  mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-3  mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-4  mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-5  mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-6  mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-7  mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-8  mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-9  mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-10 mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-11 mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-12 mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-13 mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-14 mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-15 mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-16 mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-17 mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-18 mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
3-19 mp4 1024x576   │ 1200k dash  │ avc1.4D401F 1200k video only          DASH video, mp4_dash
2-0  mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-1  mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-2  mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-3  mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-4  mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-5  mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-6  mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-7  mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-8  mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-9  mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-10 mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-11 mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-12 mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-13 mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-14 mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-15 mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-16 mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-17 mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-18 mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
2-19 mp4 1024x576   │ 1700k dash  │ avc1.4D401F 1700k video only          DASH video, mp4_dash
1-0  mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-1  mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-2  mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-3  mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-4  mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-5  mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-6  mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-7  mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-8  mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-9  mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-10 mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-11 mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-12 mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-13 mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-14 mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-15 mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-16 mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-17 mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-18 mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash
1-19 mp4 1280x720   │ 2500k dash  │ avc1.4D401F 2500k video only          DASH video, mp4_dash

@bastimeyer
Copy link
Member

Don't post media files here. I've hid the post now.

If it's an issue with the DASHStream implementation, then you'll have to provide the full DASH manifest and the full trace log, so the segment timestamps can be checked. This is off topic though and should be posted in a new thread. There is a thread about DASH timing offsets: #5201

@pokemaster974
Copy link

Don't post media files here. I've hid the post now.

If it's an issue with the DASHStream implementation, then you'll have to provide the full DASH manifest and the full trace log, so the segment timestamps can be checked. This is off topic though and should be posted in a new thread. There is a thread about DASH timing offsets: #5201

Sorry, I delete them.

@campones

This comment was marked as spam.

@campones

This comment was marked as spam.

@bastimeyer
Copy link
Member

any update on this?

Fix the plugin and send a pull request.

@campones
Copy link
Author

obviously if I could I would

@campones

This comment was marked as spam.

@BellezaEmporium
Copy link
Contributor

BellezaEmporium commented Dec 23, 2023

This will most certainly need a bit of a relift but here's my take on it : https://raw.githubusercontent.com/BellezaEmporium/streamlink/master/src/streamlink/plugins/tf1.py

There's a system of "token + refresh token" implemented in TF1's website, though I have not added the refresh logic to the code data yet, as i'm thinking on how to store account information in order from Streamlink to grab available data without having the need to reconnect.

C:\Users\....>streamlink --tf1-username=***** --tf1-password=***** https://www.tf1.fr/tf1/direct best
[cli][info] Found matching plugin tf1 for URL https://www.tf1.fr/tf1/direct
[cli][info] Available streams: 234p (worst), 360p, 576p_alt, 576p, 720p (best)
[cli][info] Opening stream: 720p (hls-multi)
[cli][info] Starting player: C:\Program Files\VideoLAN\VLC\vlc.exe
[utils.named_pipe][info] Creating pipe streamlinkpipe-45144-1-8040
[utils.named_pipe][info] Creating pipe streamlinkpipe-45144-2-715

@campones
Copy link
Author

thanks a lot for fixing this. has been quite some time now !
it's working fine on my side.
if we are talking about the token that expires every 4 hours, it was like this with the former plugin anyway.

@novazur972
Copy link

It was therefore clearly linked to the obligation to identify oneself due to the existence of MyTF1 Max, as I had assumed.

Translated from:
C'était donc bien en rapport avec l'obligation de s'identifier due à l'existence de MyTF1 Max, quel que je l'avais présumé.

@campones
Copy link
Author

campones commented Dec 24, 2023

I think to watch on their site, even before, you had to be logged in .

can't really remember, I rarely use that site anyway

@novazur972
Copy link

I think to watch on their site, even before, you had to be logged in .

No.

can't really remember, I rarely use that site anyway

me yes.

@BellezaEmporium
Copy link
Contributor

Linked to the introduction of PPV streams in MyTF1 (since Star Academy's 24/7 streams, even before I believe).

@W4RdZ
Copy link

W4RdZ commented May 8, 2024

Hello there,

@BellezaEmporium I tried your file, but i got this error :

streamlink https://www.tf1.fr/tf1/direct
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Program Files\Streamlink\bin\streamlink.exe\__main__.py", line 18, in <module>
  File "C:\Program Files\Streamlink\pkgs\streamlink_cli\main.py", line 963, in main
    error_code = run(parser)
                 ^^^^^^^^^^^
  File "C:\Program Files\Streamlink\pkgs\streamlink_cli\main.py", line 936, in run
    handle_url()
  File "C:\Program Files\Streamlink\pkgs\streamlink_cli\main.py", line 543, in handle_url
    options = setup_plugin_options(pluginname, pluginclass)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Program Files\Streamlink\pkgs\streamlink_cli\main.py", line 749, in setup_plugin_options
    value = getattr(args, parg.namespace_dest(pluginname))
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'Namespace' object has no attribute 'tf1_username'

I've tried to found out alone but i'm not a dev so i don't get shit about what's wrong :(

If i'm trying with a login throught this cmd

streamlink --tf1-username=**** https://www.tf1.fr/tf1/direct

i've this message

usage: streamlink [OPTIONS] <URL> [STREAM]
streamlink: error: unrecognized arguments: --tf1-username=****

I saw that you add this line

from streamlink.plugin.plugin import pluginargument

which is not the same when i compare to another plugin so i deleted it and added it to this line

from streamlink.plugin import Plugin, pluginargument, PluginError, pluginmatcher

but it doesn't changed anything :(

Also i don't see the tf1 help section you added using the cmd --help
I'm using streamlink 6.7.3

I would appreciate your help if you can 👍

see ya

@campones
Copy link
Author

campones commented May 8, 2024

it was never merged into the main project, curiously..
it still works perfectly on my side

@BellezaEmporium
Copy link
Contributor

image
Works fine on my side.

@bastimeyer
Copy link
Member

it was never merged into the main project, curiously..

With the recent spam/abuse in mind which I've received by other users, I'm going to say this now:

@campones The attitude you've been showing here for the past couple of years is highly annoying.

To remind you, this is a free open source software project run by volunteers in their free time. All you however do is request urgent help, attention and time without ever contributing back to the project in any way (while also abusing the software for monetary gains from what I believe by rehosting streams on your own servers - which is extra annoying to me).

If nobody submits a pull request with a fix for the plugin, then it remains broken on the master branch unless the maintainers take a look at it themselves. "The maintainers" (plural) however has been pretty much me (singular) for a very long time now because everyone else who had an actual interest in the project and/or had regularly contributed code has left (be it health issues or other various reasons).

Considering that there are additional obstacles in the way in the shape of required user accounts, I don't have much motivation fixing the plugin. If anyone however had submitted a pull request, I would have certainly given it a proper review which would have very likely led to a merge if the author could have shown me log outputs of a working plugin. This has still not happened today. I can't be bothered looking for branches on any forks where certain plugins might have been fixed.

Sideloading plugins or forking the project for personal modifications is perfectly fine (within the limits of the project's license), but if no one even thinks about contributing back via pull requests, then please don't wonder why plugins remain broken or get removed eventually. Same with any other issues regarding Streamlink's code base.

Questioning maintainer activity or constantly asking why XYZ hasn't been fixed yet, and thus once again being annoying by trying to apply pressure without contributing back yourself is just a super shitty thing to do, even as a regular user who doesn't know how to write code. Things like this make me feel less and less motivated working on the project... As said at the beginning, I've just been spammed by other users recently with the exact same demanding attitude.

@campones
Copy link
Author

campones commented May 8, 2024

I won't even bother to answer.

@BellezaEmporium
Copy link
Contributor

To answer on my behalf, I simply don't do pull requests because that would most certainly add all the other plugins I've did to the list. Which would be irrelevant in the base of this issue.

I've did a few personal plugins based on Streamlink's plugin schema, in order for me to fully understand how the technology works. If they see the light of day in the form of a PR, they might need a certain amount of rework to fit the new plugin structure.

@W4RdZ
Copy link

W4RdZ commented May 8, 2024

@BellezaEmporium I'm totally sorry to bothering you but i'm an advanced computer user but not a dev, so i just need help for few editing to makes this past post functionning. Is that community starts to be toxic as everyone else on the internet by this days ?
Just give me an hand to understand what is wrong with the code because i'm totally new in the project and i don't want to waste a lot of time to understand the whole fucking technology please !

@W4RdZ
Copy link

W4RdZ commented May 8, 2024

i mean every IT executor knows that there is that much sector that you can't be performant on every sector right ?!

@W4RdZ

This comment was marked as off-topic.

@campones
Copy link
Author

campones commented May 8, 2024

@W4RdZ I m using this with streamlink 6.5.0
just out of curiosity, are you based in France or are you using a vpn? because these channels are geoblocked

@BellezaEmporium
Copy link
Contributor

@BellezaEmporium I'm totally sorry to bothering you but i'm an advanced computer user but not a dev, so i just need help for few editing to makes this past post functionning. Is that community starts to be toxic as everyone else on the internet by this days ? Just give me an hand to understand what is wrong with the code because i'm totally new in the project and i don't want to waste a lot of time to understand the whole fucking technology please !

Might be a change in the newer versions of Streamlink. Please take note that I've made the plugin in the version that was available in December 2023. If you did an update afterwards, I might not know what has changed or not. Might be an option call change in the newer versions of Streamlink, as it seems to not recognize any of the options that are mandatory for this plugin.

@campones
Copy link
Author

campones commented May 8, 2024

yes, I have been updating one local server with latest streamlink release and indeed it doesn't work anymore

streamlink: error: unrecognized arguments: --tf1-username *** --tf1-password *** https://www.tf1.fr/tf1/direct

@W4RdZ
Copy link

W4RdZ commented May 8, 2024

@BellezaEmporium I'm totally sorry to bothering you but i'm an advanced computer user but not a dev, so i just need help for few editing to makes this past post functionning. Is that community starts to be toxic as everyone else on the internet by this days ? Just give me an hand to understand what is wrong with the code because i'm totally new in the project and i don't want to waste a lot of time to understand the whole fucking technology please !

Might be a change in the newer versions of Streamlink. Please take note that I've made the plugin in the version that was available in December 2023. If you did an update afterwards, I might not know what has changed or not. Might be an option call change in the newer versions of Streamlink, as it seems to not recognize any of the options that are mandatory for this plugin.

ty for your obvious statment 🥇 i'm asking help about the plugin you developped to make it working on the last version.
I'm not asking to repeat what i already known... (if it was the case, i would not tell what version i'm running on or what i've allready tried as rookie dev to fix it.)
So i guess i can just get the fuck out of here and install an outdated version 👍

Ty for your consideration !
Kind regards

@campones
Copy link
Author

campones commented May 8, 2024

@W4RdZ

well just downgrade the streamlink release and that should be fine?

pip uninstall streamlink
pip install streamlink==6.5.0

@campones
Copy link
Author

campones commented May 8, 2024

must be related to this
https://streamlink.github.io/deprecations.html

@bastimeyer
Copy link
Member

You are not sideloading the plugin but instead overwriting the regular plugin module, which is unsupported. You are not supposed to touch any files in a Python distribution.

Read the documentation on how to sideload new or override existing plugins:
https://streamlink.github.io/cli/plugin-sideloading.html

The error you're seeing is a consequence of overwriting the regular plugin file and trying to add new plugin arguments. This is explicitly unsupported with the addition of lazy plugin loading in 6.6.0:
https://streamlink.github.io/changelog.html#streamlink-6-6-0-2024-02-16

@BellezaEmporium
Copy link
Contributor

You are not sideloading the plugin but instead overwriting the regular plugin module, which is unsupported. You are not supposed to touch any files in a Python distribution.

Read the documentation on how to sideload new or override existing plugins: https://streamlink.github.io/cli/plugin-sideloading.html

The error you're seeing is a consequence of overwriting the regular plugin file and trying to add new plugin arguments. This is explicitly unsupported with the addition of lazy plugin loading in 6.6.0: https://streamlink.github.io/changelog.html#streamlink-6-6-0-2024-02-16

Ah well thanks for pointing me to the right direction. I'll take a check soon then.

@W4RdZ
Copy link

W4RdZ commented May 9, 2024

You are not sideloading the plugin but instead overwriting the regular plugin module, which is unsupported. You are not supposed to touch any files in a Python distribution.

Read the documentation on how to sideload new or override existing plugins: https://streamlink.github.io/cli/plugin-sideloading.html

The error you're seeing is a consequence of overwriting the regular plugin file and trying to add new plugin arguments. This is explicitly unsupported with the addition of lazy plugin loading in 6.6.0: https://streamlink.github.io/changelog.html#streamlink-6-6-0-2024-02-16

Thanks, loading the plugin from the right path works, but i think the code must be reworked a bit to fit with the update.

Maybe you can help me to understand which part of BellezaEmporium code tries to add arguments (Sorry, i really have only basics on general dev.)

In a first approch i thought it was about these parts of the code :

@pluginargument(
    "username",
    requires=["password"],
    metavar="USERNAME",
    help="The username used to register with tf1.fr.",
)
@pluginargument(
    "password",
    prompt="Enter tf1.fr account password",
    sensitive=True,
    metavar="PASSWORD",
    help="A tf1.fr account password to use with --tf1-username.",
)

and

    def _get_streams(self):
        if not self.get_option("username"):
            log.error(
                "In order to access your content, TF1 requires an account you must login with, using "
                + "--tf1-username and --tf1-password",
            )
            return
        if not self.login(self.get_option("username"), self.get_option("password")):
            log.error(
                "Could not authenticate, check your username and password.")
            return

        channel, channel_id = self._get_channel()
        log.debug(f"Found channel {channel} ({channel_id})")

        code, data = self._api_call(channel_id)
        if code != 200:
            log.error(data)
            return

        return HLSStream.parse_variant_playlist(self.session, data)

So i've edited it for this :

@pluginargument(
    "username",
    required=True,
    requires=["password"],
    metavar="USERNAME",
    help="Your TF1 account username",
)
@pluginargument(
    "password",
    required=True,
    sensitive=True,
    metavar="PASSWORD",
    help="Your TF1 account password",
)

and

    def _get_streams(self):
        if not self.login(self.get_option("username"), self.get_option("password")):
            log.error("Failed to login, check username and password")
            return

        channel, channel_id = self._get_channel()
        log.debug(f"Found channel {channel} ({channel_id})")

        code, data = self._api_call(channel_id)
        if code != 200:
            log.error(data)
            return

        return HLSStream.parse_variant_playlist(self.session, data)

But the error message remains almost the same as original BellezaEmporium code, only the line numbers change because of my editing :

Enter tf1 password:
[cli][info] Found matching plugin tf1 for URL https://www.tf1.fr/tf1/direct
Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "C:\Program Files\Streamlink\bin\streamlink.exe\__main__.py", line 18, in <module>
  File "C:\Program Files\Streamlink\pkgs\streamlink_cli\main.py", line 963, in main
    error_code = run(parser)
                 ^^^^^^^^^^^
  File "C:\Program Files\Streamlink\pkgs\streamlink_cli\main.py", line 936, in run
    handle_url()
  File "C:\Program Files\Streamlink\pkgs\streamlink_cli\main.py", line 556, in handle_url
    streams = fetch_streams(plugin)
              ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Program Files\Streamlink\pkgs\streamlink_cli\main.py", line 454, in fetch_streams
    return plugin.streams(stream_types=args.stream_types,
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Program Files\Streamlink\pkgs\streamlink\plugin\plugin.py", line 387, in streams
    ostreams = self._get_streams()
               ^^^^^^^^^^^^^^^^^^^
  File "C:\Users\***\AppData\Roaming\streamlink\plugins\tf1.py", line 156, in _get_streams
    if not self.login(self.get_option("username"), self.get_option("password")):
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\***\AppData\Roaming\streamlink\plugins\tf1.py", line 149, in login
    if auth_check() == True:
       ^^^^^^^^^^^^
  File "C:\Users\***\AppData\Roaming\streamlink\plugins\tf1.py", line 134, in auth_check
    "uid": res.json()['userInfo']['UID'],
           ~~~~~~~~~~^^^^^^^^^^^^
KeyError: 'userInfo'

As few as i comprehend, it must point on this part of the code :

def auth_check():
            res = self.session.http.post(
            self.auth_url,
            data=dict(
                loginID=username,
                password=password,
                APIKey=self.gigya_api_key,
                includeUserInfo="true"
            ),
            headers={"Referer": self.url, "User-Agent": useragents.IPHONE})

            # If TF1 login is successful, get Gigya token.
            if res.status_code == 200:
                # make the session request to get the correct cookies
                session_res = self.session.http.post(
                    self.session_url,
                    data=json.dumps({
                        "uid": res.json()['userInfo']['UID'],
                        "signature": res.json()['userInfo']['UIDSignature'],
                        "timestamp": int(res.json()['userInfo']['signatureTimestamp']),
                        "consent_ids": ["1", "2", "3", "4", "10001", "10003", "10005", "10007", "10013", "10015", "10017", "10019", "10009", "10011", "13002", "13001", "10004", "10014", "10016", "10018", "10020", "10010", "10012", "10006", "10008"]
                    })
                )
                if session_res.status_code == 200:
                    self.user_token = session_res.json()['token']
                    return True
                else:
                    return False
            else:
                return False

        
        if auth_check() == True:
            log.debug("Already authenticated, skipping authentication")
            return True
        else:
            return False

I've the feeling it's more about change like these whiches make the code not working #5807 #5814

But for me it's getting too complicated 😒

@bastimeyer
Copy link
Member

The reason for the error you've posted is simple: the third party plugin does not do any error handling and HTTP response validation, hence the KeyError being raised from trying to access a specific attribute on the server's JSON response. It has nothing to do with #5807 and related at all.

So I'm saying this one again. If you want this plugin fixed, then open a pull request. I'm not going to review any code on any user branches or code downloaded from somewhere else.

I can already tell you though that all the changes made in the linked plugin code are implemented pretty poorly and require a whole rewrite.

@W4RdZ
Copy link

W4RdZ commented May 9, 2024

i'll make that 😎

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
plugin issue A Plugin does not work correctly restriction: account needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants