]> jfr.im git - yt-dlp.git/commitdiff
[cleanup] Remove dead extractors (#8604)
authorsepro <redacted>
Sun, 26 Nov 2023 03:09:59 +0000 (04:09 +0100)
committerGitHub <redacted>
Sun, 26 Nov 2023 03:09:59 +0000 (03:09 +0000)
Closes #1609, Closes #3232, Closes #4763, Closes #6026, Closes #6322, Closes #7912
Authored by: seproDev

125 files changed:
yt_dlp/extractor/_extractors.py
yt_dlp/extractor/airmozilla.py [deleted file]
yt_dlp/extractor/aol.py
yt_dlp/extractor/atttechchannel.py [deleted file]
yt_dlp/extractor/behindkink.py
yt_dlp/extractor/bet.py
yt_dlp/extractor/bfi.py
yt_dlp/extractor/biqle.py [deleted file]
yt_dlp/extractor/bitwave.py [deleted file]
yt_dlp/extractor/bleacherreport.py
yt_dlp/extractor/br.py
yt_dlp/extractor/breakcom.py [deleted file]
yt_dlp/extractor/byutv.py
yt_dlp/extractor/camwithher.py [deleted file]
yt_dlp/extractor/carambatv.py [deleted file]
yt_dlp/extractor/channel9.py [deleted file]
yt_dlp/extractor/chirbit.py [deleted file]
yt_dlp/extractor/cinchcast.py [deleted file]
yt_dlp/extractor/clipsyndicate.py [deleted file]
yt_dlp/extractor/cloudy.py [deleted file]
yt_dlp/extractor/clubic.py
yt_dlp/extractor/cmt.py
yt_dlp/extractor/daftsex.py [deleted file]
yt_dlp/extractor/defense.py [deleted file]
yt_dlp/extractor/dhm.py
yt_dlp/extractor/dotsub.py [deleted file]
yt_dlp/extractor/echomsk.py [deleted file]
yt_dlp/extractor/ehow.py [deleted file]
yt_dlp/extractor/elevensports.py [deleted file]
yt_dlp/extractor/ellentube.py [deleted file]
yt_dlp/extractor/engadget.py [deleted file]
yt_dlp/extractor/escapist.py [deleted file]
yt_dlp/extractor/esri.py [deleted file]
yt_dlp/extractor/expotv.py [deleted file]
yt_dlp/extractor/extremetube.py [deleted file]
yt_dlp/extractor/fourzerostudio.py [deleted file]
yt_dlp/extractor/foxgay.py [deleted file]
yt_dlp/extractor/fusion.py [deleted file]
yt_dlp/extractor/generic.py
yt_dlp/extractor/gfycat.py [deleted file]
yt_dlp/extractor/groupon.py
yt_dlp/extractor/helsinki.py [deleted file]
yt_dlp/extractor/hitbox.py [deleted file]
yt_dlp/extractor/howcast.py [deleted file]
yt_dlp/extractor/howstuffworks.py [deleted file]
yt_dlp/extractor/keezmovies.py [deleted file]
yt_dlp/extractor/kinja.py
yt_dlp/extractor/laola1tv.py [deleted file]
yt_dlp/extractor/linuxacademy.py [deleted file]
yt_dlp/extractor/m6.py [deleted file]
yt_dlp/extractor/meta.py [deleted file]
yt_dlp/extractor/metacafe.py [deleted file]
yt_dlp/extractor/mgoon.py [deleted file]
yt_dlp/extractor/miomio.py [deleted file]
yt_dlp/extractor/mnet.py [deleted file]
yt_dlp/extractor/moevideo.py [deleted file]
yt_dlp/extractor/mofosex.py [deleted file]
yt_dlp/extractor/movieclips.py [deleted file]
yt_dlp/extractor/msn.py
yt_dlp/extractor/mwave.py [deleted file]
yt_dlp/extractor/mychannels.py [deleted file]
yt_dlp/extractor/myvi.py [deleted file]
yt_dlp/extractor/newstube.py [deleted file]
yt_dlp/extractor/nick.py
yt_dlp/extractor/normalboots.py [deleted file]
yt_dlp/extractor/nosvideo.py [deleted file]
yt_dlp/extractor/nrl.py
yt_dlp/extractor/ooyala.py [deleted file]
yt_dlp/extractor/pandoratv.py [deleted file]
yt_dlp/extractor/people.py [deleted file]
yt_dlp/extractor/playfm.py [deleted file]
yt_dlp/extractor/plays.py [deleted file]
yt_dlp/extractor/playvid.py [deleted file]
yt_dlp/extractor/porncom.py [deleted file]
yt_dlp/extractor/pornez.py [deleted file]
yt_dlp/extractor/pornhd.py [deleted file]
yt_dlp/extractor/radiobremen.py [deleted file]
yt_dlp/extractor/recurbate.py [deleted file]
yt_dlp/extractor/rice.py [deleted file]
yt_dlp/extractor/rtl2.py
yt_dlp/extractor/rtvnh.py [deleted file]
yt_dlp/extractor/ruhd.py [deleted file]
yt_dlp/extractor/scte.py
yt_dlp/extractor/shared.py [deleted file]
yt_dlp/extractor/sky.py
yt_dlp/extractor/spankwire.py [deleted file]
yt_dlp/extractor/srmediathek.py
yt_dlp/extractor/streamcloud.py [deleted file]
yt_dlp/extractor/swrmediathek.py [deleted file]
yt_dlp/extractor/techtalks.py [deleted file]
yt_dlp/extractor/telecinco.py
yt_dlp/extractor/tinypic.py [deleted file]
yt_dlp/extractor/tokentube.py [deleted file]
yt_dlp/extractor/toypics.py
yt_dlp/extractor/trilulilu.py [deleted file]
yt_dlp/extractor/tube8.py
yt_dlp/extractor/tunepk.py [deleted file]
yt_dlp/extractor/tvnet.py [deleted file]
yt_dlp/extractor/tvnow.py [deleted file]
yt_dlp/extractor/twentyfourvideo.py [deleted file]
yt_dlp/extractor/unscripted.py [deleted file]
yt_dlp/extractor/veehd.py [deleted file]
yt_dlp/extractor/vice.py
yt_dlp/extractor/vidbit.py [deleted file]
yt_dlp/extractor/vimple.py [deleted file]
yt_dlp/extractor/vodlocker.py [deleted file]
yt_dlp/extractor/voicerepublic.py [deleted file]
yt_dlp/extractor/voot.py
yt_dlp/extractor/voxmedia.py
yt_dlp/extractor/vrak.py [deleted file]
yt_dlp/extractor/vrv.py [deleted file]
yt_dlp/extractor/vshare.py [deleted file]
yt_dlp/extractor/vupload.py [deleted file]
yt_dlp/extractor/vyborymos.py [deleted file]
yt_dlp/extractor/vzaar.py [deleted file]
yt_dlp/extractor/wakanim.py [deleted file]
yt_dlp/extractor/watchbox.py [deleted file]
yt_dlp/extractor/watchindianporn.py [deleted file]
yt_dlp/extractor/willow.py [deleted file]
yt_dlp/extractor/xbef.py [deleted file]
yt_dlp/extractor/xtube.py [deleted file]
yt_dlp/extractor/xuite.py [deleted file]
yt_dlp/extractor/yesjapan.py [deleted file]
yt_dlp/extractor/yinyuetai.py [deleted file]
yt_dlp/extractor/ynet.py [deleted file]

index ad8c7d6611456cdc53ed97b3ea83cd88fcbce92e..9b96bd5b4554bd4e8312b7403a1ff85819322bd5 100644 (file)
@@ -77,7 +77,6 @@
     WyborczaPodcastIE,
     WyborczaVideoIE,
 )
     WyborczaPodcastIE,
     WyborczaVideoIE,
 )
-from .airmozilla import AirMozillaIE
 from .airtv import AirTVIE
 from .aitube import AitubeKZVideoIE
 from .aljazeera import AlJazeeraIE
 from .airtv import AirTVIE
 from .aitube import AitubeKZVideoIE
 from .aljazeera import AlJazeeraIE
 from .arnes import ArnesIE
 from .atresplayer import AtresPlayerIE
 from .atscaleconf import AtScaleConfEventIE
 from .arnes import ArnesIE
 from .atresplayer import AtresPlayerIE
 from .atscaleconf import AtScaleConfEventIE
-from .atttechchannel import ATTTechChannelIE
 from .atvat import ATVAtIE
 from .audimedia import AudiMediaIE
 from .audioboom import AudioBoomIE
 from .atvat import ATVAtIE
 from .audimedia import AudiMediaIE
 from .audioboom import AudioBoomIE
     BitChuteIE,
     BitChuteChannelIE,
 )
     BitChuteIE,
     BitChuteChannelIE,
 )
-from .bitwave import (
-    BitwaveReplayIE,
-    BitwaveStreamIE,
-)
-from .biqle import BIQLEIE
 from .blackboardcollaborate import BlackboardCollaborateIE
 from .bleacherreport import (
     BleacherReportIE,
 from .blackboardcollaborate import BlackboardCollaborateIE
 from .bleacherreport import (
     BleacherReportIE,
 from .box import BoxIE
 from .boxcast import BoxCastVideoIE
 from .bpb import BpbIE
 from .box import BoxIE
 from .boxcast import BoxCastVideoIE
 from .bpb import BpbIE
-from .br import (
-    BRIE,
-    BRMediathekIE,
-)
+from .br import BRIE
 from .bravotv import BravoTVIE
 from .brainpop import (
     BrainPOPIE,
 from .bravotv import BravoTVIE
 from .brainpop import (
     BrainPOPIE,
     BrainPOPFrIE,
     BrainPOPIlIE,
 )
     BrainPOPFrIE,
     BrainPOPIlIE,
 )
-from .breakcom import BreakIE
 from .breitbart import BreitBartIE
 from .brightcove import (
     BrightcoveLegacyIE,
 from .breitbart import BreitBartIE
 from .brightcove import (
     BrightcoveLegacyIE,
 from .cammodels import CamModelsIE
 from .camsoda import CamsodaIE
 from .camtasia import CamtasiaEmbedIE
 from .cammodels import CamModelsIE
 from .camsoda import CamsodaIE
 from .camtasia import CamtasiaEmbedIE
-from .camwithher import CamWithHerIE
 from .canal1 import Canal1IE
 from .canalalpha import CanalAlphaIE
 from .canalplus import CanalplusIE
 from .canalc2 import Canalc2IE
 from .caracoltv import CaracolTvPlayIE
 from .canal1 import Canal1IE
 from .canalalpha import CanalAlphaIE
 from .canalplus import CanalplusIE
 from .canalc2 import Canalc2IE
 from .caracoltv import CaracolTvPlayIE
-from .carambatv import (
-    CarambaTVIE,
-    CarambaTVPageIE,
-)
 from .cartoonnetwork import CartoonNetworkIE
 from .cbc import (
     CBCIE,
 from .cartoonnetwork import CartoonNetworkIE
 from .cbc import (
     CBCIE,
 from .cellebrite import CellebriteIE
 from .ceskatelevize import CeskaTelevizeIE
 from .cgtn import CGTNIE
 from .cellebrite import CellebriteIE
 from .ceskatelevize import CeskaTelevizeIE
 from .cgtn import CGTNIE
-from .channel9 import Channel9IE
 from .charlierose import CharlieRoseIE
 from .chaturbate import ChaturbateIE
 from .chilloutzone import ChilloutzoneIE
 from .charlierose import CharlieRoseIE
 from .chaturbate import ChaturbateIE
 from .chilloutzone import ChilloutzoneIE
     ChingariIE,
     ChingariUserIE,
 )
     ChingariIE,
     ChingariUserIE,
 )
-from .chirbit import (
-    ChirbitIE,
-    ChirbitProfileIE,
-)
-from .cinchcast import CinchcastIE
 from .cinemax import CinemaxIE
 from .cinetecamilano import CinetecaMilanoIE
 from .cineverse import (
 from .cinemax import CinemaxIE
 from .cinetecamilano import CinetecaMilanoIE
 from .cineverse import (
 from .cliphunter import CliphunterIE
 from .clippit import ClippitIE
 from .cliprs import ClipRsIE
 from .cliphunter import CliphunterIE
 from .clippit import ClippitIE
 from .cliprs import ClipRsIE
-from .clipsyndicate import ClipsyndicateIE
 from .closertotruth import CloserToTruthIE
 from .cloudflarestream import CloudflareStreamIE
 from .closertotruth import CloserToTruthIE
 from .cloudflarestream import CloudflareStreamIE
-from .cloudy import CloudyIE
 from .clubic import ClubicIE
 from .clyp import ClypIE
 from .cmt import CMTIE
 from .clubic import ClubicIE
 from .clyp import ClypIE
 from .cmt import CMTIE
     DacastVODIE,
     DacastPlaylistIE,
 )
     DacastVODIE,
     DacastPlaylistIE,
 )
-from .daftsex import DaftsexIE
 from .dailymail import DailyMailIE
 from .dailymotion import (
     DailymotionIE,
 from .dailymail import DailyMailIE
 from .dailymotion import (
     DailymotionIE,
 from .dfb import DFBIE
 from .dhm import DHMIE
 from .digg import DiggIE
 from .dfb import DFBIE
 from .dhm import DHMIE
 from .digg import DiggIE
-from .dotsub import DotsubIE
 from .douyutv import (
     DouyuShowIE,
     DouyuTVIE,
 from .douyutv import (
     DouyuShowIE,
     DouyuTVIE,
     DubokuPlaylistIE
 )
 from .dumpert import DumpertIE
     DubokuPlaylistIE
 )
 from .dumpert import DumpertIE
-from .defense import DefenseGouvFrIE
 from .deuxm import (
     DeuxMIE,
     DeuxMNewsIE
 from .deuxm import (
     DeuxMIE,
     DeuxMNewsIE
 from .eagleplatform import EaglePlatformIE, ClipYouEmbedIE
 from .ebaumsworld import EbaumsWorldIE
 from .ebay import EbayIE
 from .eagleplatform import EaglePlatformIE, ClipYouEmbedIE
 from .ebaumsworld import EbaumsWorldIE
 from .ebay import EbayIE
-from .echomsk import EchoMskIE
 from .egghead import (
     EggheadCourseIE,
     EggheadLessonIE,
 )
 from .egghead import (
     EggheadCourseIE,
     EggheadLessonIE,
 )
-from .ehow import EHowIE
 from .eighttracks import EightTracksIE
 from .einthusan import EinthusanIE
 from .eitb import EitbIE
 from .eighttracks import EightTracksIE
 from .einthusan import EinthusanIE
 from .eitb import EitbIE
-from .elevensports import ElevenSportsIE
-from .ellentube import (
-    EllenTubeIE,
-    EllenTubeVideoIE,
-    EllenTubePlaylistIE,
-)
 from .elonet import ElonetIE
 from .elpais import ElPaisIE
 from .eltrecetv import ElTreceTVIE
 from .embedly import EmbedlyIE
 from .elonet import ElonetIE
 from .elpais import ElPaisIE
 from .eltrecetv import ElTreceTVIE
 from .embedly import EmbedlyIE
-from .engadget import EngadgetIE
 from .epicon import (
     EpiconIE,
     EpiconSeriesIE,
 from .epicon import (
     EpiconIE,
     EpiconSeriesIE,
     ERTFlixIE,
     ERTWebtvEmbedIE,
 )
     ERTFlixIE,
     ERTWebtvEmbedIE,
 )
-from .escapist import EscapistIE
 from .espn import (
     ESPNIE,
     WatchESPNIE,
 from .espn import (
     ESPNIE,
     WatchESPNIE,
     FiveThirtyEightIE,
     ESPNCricInfoIE,
 )
     FiveThirtyEightIE,
     ESPNCricInfoIE,
 )
-from .esri import EsriVideoIE
 from .ettutv import EttuTvIE
 from .europa import EuropaIE, EuroParlWebstreamIE
 from .europeantour import EuropeanTourIE
 from .eurosport import EurosportIE
 from .euscreen import EUScreenIE
 from .ettutv import EttuTvIE
 from .europa import EuropaIE, EuroParlWebstreamIE
 from .europeantour import EuropeanTourIE
 from .eurosport import EurosportIE
 from .euscreen import EUScreenIE
-from .expotv import ExpoTVIE
 from .expressen import ExpressenIE
 from .expressen import ExpressenIE
-from .extremetube import ExtremeTubeIE
 from .eyedotv import EyedoTVIE
 from .facebook import (
     FacebookIE,
 from .eyedotv import EyedoTVIE
 from .facebook import (
     FacebookIE,
     PornerBrosIE,
     FuxIE,
 )
     PornerBrosIE,
     FuxIE,
 )
-from .fourzerostudio import (
-    FourZeroStudioArchiveIE,
-    FourZeroStudioClipIE,
-)
 from .fox import FOXIE
 from .fox9 import (
     FOX9IE,
     FOX9NewsIE,
 )
 from .fox import FOXIE
 from .fox9 import (
     FOX9IE,
     FOX9NewsIE,
 )
-from .foxgay import FoxgayIE
 from .foxnews import (
     FoxNewsIE,
     FoxNewsArticleIE,
 from .foxnews import (
     FoxNewsIE,
     FoxNewsArticleIE,
 )
 from .funk import FunkIE
 from .funker530 import Funker530IE
 )
 from .funk import FunkIE
 from .funker530 import Funker530IE
-from .fusion import FusionIE
 from .fuyintv import FuyinTVIE
 from .gab import (
     GabTVIE,
 from .fuyintv import FuyinTVIE
 from .gab import (
     GabTVIE,
     GettrIE,
     GettrStreamingIE,
 )
     GettrIE,
     GettrStreamingIE,
 )
-from .gfycat import GfycatIE
 from .giantbomb import GiantBombIE
 from .giga import GigaIE
 from .glide import GlideIE
 from .giantbomb import GiantBombIE
 from .giga import GigaIE
 from .glide import GlideIE
 from .hearthisat import HearThisAtIE
 from .heise import HeiseIE
 from .hellporno import HellPornoIE
 from .hearthisat import HearThisAtIE
 from .heise import HeiseIE
 from .hellporno import HellPornoIE
-from .helsinki import HelsinkiIE
 from .hgtv import HGTVComShowIE
 from .hketv import HKETVIE
 from .hidive import HiDiveIE
 from .historicfilms import HistoricFilmsIE
 from .hgtv import HGTVComShowIE
 from .hketv import HKETVIE
 from .hidive import HiDiveIE
 from .historicfilms import HistoricFilmsIE
-from .hitbox import HitboxIE, HitboxLiveIE
 from .hitrecord import HitRecordIE
 from .hollywoodreporter import (
     HollywoodReporterIE,
 from .hitrecord import HitRecordIE
 from .hollywoodreporter import (
     HollywoodReporterIE,
     HotStarSeasonIE,
     HotStarSeriesIE,
 )
     HotStarSeasonIE,
     HotStarSeriesIE,
 )
-from .howcast import HowcastIE
-from .howstuffworks import HowStuffWorksIE
 from .hrefli import HrefLiRedirectIE
 from .hrfensehen import HRFernsehenIE
 from .hrti import (
 from .hrefli import HrefLiRedirectIE
 from .hrfensehen import HRFernsehenIE
 from .hrti import (
 from .kankanews import KankaNewsIE
 from .karaoketv import KaraoketvIE
 from .karrierevideos import KarriereVideosIE
 from .kankanews import KankaNewsIE
 from .karaoketv import KaraoketvIE
 from .karrierevideos import KarriereVideosIE
-from .keezmovies import KeezMoviesIE
 from .kelbyone import KelbyOneIE
 from .khanacademy import (
     KhanAcademyIE,
 from .kelbyone import KelbyOneIE
 from .khanacademy import (
     KhanAcademyIE,
     LA7PodcastEpisodeIE,
     LA7PodcastIE,
 )
     LA7PodcastEpisodeIE,
     LA7PodcastIE,
 )
-from .laola1tv import (
-    Laola1TvEmbedIE,
-    Laola1TvIE,
-    EHFTVIE,
-    ITTFIE,
-)
 from .lastfm import (
     LastFMIE,
     LastFMPlaylistIE,
 from .lastfm import (
     LastFMIE,
     LastFMPlaylistIE,
     LinkedInLearningIE,
     LinkedInLearningCourseIE,
 )
     LinkedInLearningIE,
     LinkedInLearningCourseIE,
 )
-from .linuxacademy import LinuxAcademyIE
 from .liputan6 import Liputan6IE
 from .listennotes import ListenNotesIE
 from .litv import LiTVIE
 from .liputan6 import Liputan6IE
 from .listennotes import ListenNotesIE
 from .litv import LiTVIE
     LyndaIE,
     LyndaCourseIE
 )
     LyndaIE,
     LyndaCourseIE
 )
-from .m6 import M6IE
 from .magellantv import MagellanTVIE
 from .magentamusik360 import MagentaMusik360IE
 from .mailru import (
 from .magellantv import MagellanTVIE
 from .magentamusik360 import MagentaMusik360IE
 from .mailru import (
 from .megaphone import MegaphoneIE
 from .meipai import MeipaiIE
 from .melonvod import MelonVODIE
 from .megaphone import MegaphoneIE
 from .meipai import MeipaiIE
 from .melonvod import MelonVODIE
-from .meta import METAIE
-from .metacafe import MetacafeIE
 from .metacritic import MetacriticIE
 from .metacritic import MetacriticIE
-from .mgoon import MgoonIE
 from .mgtv import MGTVIE
 from .miaopai import MiaoPaiIE
 from .microsoftstream import MicrosoftStreamIE
 from .mgtv import MGTVIE
 from .miaopai import MiaoPaiIE
 from .microsoftstream import MicrosoftStreamIE
 )
 from .ministrygrid import MinistryGridIE
 from .minoto import MinotoIE
 )
 from .ministrygrid import MinistryGridIE
 from .minoto import MinotoIE
-from .miomio import MioMioIE
 from .mirrativ import (
     MirrativIE,
     MirrativUserIE,
 from .mirrativ import (
     MirrativIE,
     MirrativUserIE,
     MLBArticleIE,
 )
 from .mlssoccer import MLSSoccerIE
     MLBArticleIE,
 )
 from .mlssoccer import MLSSoccerIE
-from .mnet import MnetIE
 from .mocha import MochaVideoIE
 from .mocha import MochaVideoIE
-from .moevideo import MoeVideoIE
-from .mofosex import (
-    MofosexIE,
-    MofosexEmbedIE,
-)
 from .mojvideo import MojvideoIE
 from .monstercat import MonstercatIE
 from .morningstar import MorningstarIE
 from .mojvideo import MojvideoIE
 from .monstercat import MonstercatIE
 from .morningstar import MorningstarIE
     MotherlessGalleryIE,
 )
 from .motorsport import MotorsportIE
     MotherlessGalleryIE,
 )
 from .motorsport import MotorsportIE
-from .movieclips import MovieClipsIE
 from .moviepilot import MoviepilotIE
 from .moview import MoviewPlayIE
 from .moviezine import MoviezineIE
 from .moviepilot import MoviepilotIE
 from .moview import MoviewPlayIE
 from .moviezine import MoviezineIE
     MusicdexArtistIE,
     MusicdexPlaylistIE,
 )
     MusicdexArtistIE,
     MusicdexPlaylistIE,
 )
-from .mwave import MwaveIE, MwaveMeetGreetIE
 from .mxplayer import (
     MxplayerIE,
     MxplayerShowIE,
 )
 from .mxplayer import (
     MxplayerIE,
     MxplayerShowIE,
 )
-from .mychannels import MyChannelsIE
 from .myspace import MySpaceIE, MySpaceAlbumIE
 from .myspass import MySpassIE
 from .myspace import MySpaceIE, MySpaceAlbumIE
 from .myspass import MySpassIE
-from .myvi import (
-    MyviIE,
-    MyviEmbedIE,
-)
 from .myvideoge import MyVideoGeIE
 from .myvidster import MyVidsterIE
 from .mzaalo import MzaaloIE
 from .myvideoge import MyVideoGeIE
 from .myvidster import MyVidsterIE
 from .mzaalo import MzaaloIE
     NewgroundsUserIE,
 )
 from .newspicks import NewsPicksIE
     NewgroundsUserIE,
 )
 from .newspicks import NewsPicksIE
-from .newstube import NewstubeIE
 from .newsy import NewsyIE
 from .nextmedia import (
     NextMediaIE,
 from .newsy import NewsyIE
 from .nextmedia import (
     NextMediaIE,
     NickIE,
     NickBrIE,
     NickDeIE,
     NickIE,
     NickBrIE,
     NickDeIE,
-    NickNightIE,
     NickRuIE,
 )
 from .niconico import (
     NickRuIE,
 )
 from .niconico import (
 from .nonktube import NonkTubeIE
 from .noodlemagazine import NoodleMagazineIE
 from .noovo import NoovoIE
 from .nonktube import NonkTubeIE
 from .noodlemagazine import NoodleMagazineIE
 from .noovo import NoovoIE
-from .normalboots import NormalbootsIE
-from .nosvideo import NosVideoIE
 from .nosnl import NOSNLArticleIE
 from .nova import (
     NovaEmbedIE,
 from .nosnl import NOSNLArticleIE
 from .nova import (
     NovaEmbedIE,
     OnetPlIE,
 )
 from .onionstudios import OnionStudiosIE
     OnetPlIE,
 )
 from .onionstudios import OnionStudiosIE
-from .ooyala import (
-    OoyalaIE,
-    OoyalaExternalIE,
-)
 from .opencast import (
     OpencastIE,
     OpencastPlaylistIE,
 from .opencast import (
     OpencastIE,
     OpencastPlaylistIE,
     PalcoMP3ArtistIE,
     PalcoMP3VideoIE,
 )
     PalcoMP3ArtistIE,
     PalcoMP3VideoIE,
 )
-from .pandoratv import PandoraTVIE
 from .panopto import (
     PanoptoIE,
     PanoptoListIE,
 from .panopto import (
     PanoptoIE,
     PanoptoListIE,
     PelotonIE,
     PelotonLiveIE
 )
     PelotonIE,
     PelotonLiveIE
 )
-from .people import PeopleIE
 from .performgroup import PerformGroupIE
 from .periscope import (
     PeriscopeIE,
 from .performgroup import PerformGroupIE
 from .periscope import (
     PeriscopeIE,
     PlatziIE,
     PlatziCourseIE,
 )
     PlatziIE,
     PlatziCourseIE,
 )
-from .playfm import PlayFMIE
 from .playplustv import PlayPlusTVIE
 from .playplustv import PlayPlusTVIE
-from .plays import PlaysTVIE
 from .playstuff import PlayStuffIE
 from .playsuisse import PlaySuisseIE
 from .playtvak import PlaytvakIE
 from .playstuff import PlayStuffIE
 from .playsuisse import PlaySuisseIE
 from .playtvak import PlaytvakIE
-from .playvid import PlayvidIE
 from .playwire import PlaywireIE
 from .plutotv import PlutoTVIE
 from .pluralsight import (
 from .playwire import PlaywireIE
 from .plutotv import PlutoTVIE
 from .pluralsight import (
 from .popcorntv import PopcornTVIE
 from .porn91 import Porn91IE
 from .pornbox import PornboxIE
 from .popcorntv import PopcornTVIE
 from .porn91 import Porn91IE
 from .pornbox import PornboxIE
-from .porncom import PornComIE
 from .pornflip import PornFlipIE
 from .pornflip import PornFlipIE
-from .pornhd import PornHdIE
 from .pornhub import (
     PornHubIE,
     PornHubUserIE,
 from .pornhub import (
     PornHubIE,
     PornHubUserIE,
 from .pornotube import PornotubeIE
 from .pornovoisines import PornoVoisinesIE
 from .pornoxo import PornoXOIE
 from .pornotube import PornotubeIE
 from .pornovoisines import PornoVoisinesIE
 from .pornoxo import PornoXOIE
-from .pornez import PornezIE
 from .puhutv import (
     PuhuTVIE,
     PuhuTVSerieIE,
 from .puhutv import (
     PuhuTVIE,
     PuhuTVSerieIE,
 )
 from .radiode import RadioDeIE
 from .radiojavan import RadioJavanIE
 )
 from .radiode import RadioDeIE
 from .radiojavan import RadioJavanIE
-from .radiobremen import RadioBremenIE
 from .radiofrance import (
     FranceCultureIE,
     RadioFranceIE,
 from .radiofrance import (
     FranceCultureIE,
     RadioFranceIE,
     RCTIPlusTVIE,
 )
 from .rds import RDSIE
     RCTIPlusTVIE,
 )
 from .rds import RDSIE
-from .recurbate import RecurbateIE
 from .redbee import ParliamentLiveUKIE, RTBFIE
 from .redbulltv import (
     RedBullTVIE,
 from .redbee import ParliamentLiveUKIE, RTBFIE
 from .redbulltv import (
     RedBullTVIE,
 from .reuters import ReutersIE
 from .reverbnation import ReverbNationIE
 from .rheinmaintv import RheinMainTVIE
 from .reuters import ReutersIE
 from .reverbnation import ReverbNationIE
 from .rheinmaintv import RheinMainTVIE
-from .rice import RICEIE
 from .rmcdecouverte import RMCDecouverteIE
 from .rockstargames import RockstarGamesIE
 from .rokfin import (
 from .rmcdecouverte import RMCDecouverteIE
 from .rockstargames import RockstarGamesIE
 from .rokfin import (
     RTLLuLiveIE,
     RTLLuRadioIE,
 )
     RTLLuLiveIE,
     RTLLuRadioIE,
 )
-from .rtl2 import (
-    RTL2IE,
-    RTL2YouIE,
-    RTL2YouSeriesIE,
-)
+from .rtl2 import RTL2IE
 from .rtnews import (
     RTNewsIE,
     RTDocumentryIE,
 from .rtnews import (
     RTNewsIE,
     RTDocumentryIE,
     RTVEInfantilIE,
     RTVETelevisionIE,
 )
     RTVEInfantilIE,
     RTVETelevisionIE,
 )
-from .rtvnh import RTVNHIE
 from .rtvs import RTVSIE
 from .rtvslo import RTVSLOIE
 from .rtvs import RTVSIE
 from .rtvslo import RTVSLOIE
-from .ruhd import RUHDIE
 from .rule34video import Rule34VideoIE
 from .rumble import (
     RumbleEmbedIE,
 from .rule34video import Rule34VideoIE
 from .rumble import (
     RumbleEmbedIE,
     ShahidIE,
     ShahidShowIE,
 )
     ShahidIE,
     ShahidShowIE,
 )
-from .shared import (
-    SharedIE,
-    VivoIE,
-)
 from .sharevideos import ShareVideosEmbedIE
 from .sibnet import SibnetEmbedIE
 from .shemaroome import ShemarooMeIE
 from .sharevideos import ShareVideosEmbedIE
 from .sibnet import SibnetEmbedIE
 from .shemaroome import ShemarooMeIE
     SpankBangIE,
     SpankBangPlaylistIE,
 )
     SpankBangIE,
     SpankBangPlaylistIE,
 )
-from .spankwire import SpankwireIE
 from .spiegel import SpiegelIE
 from .spike import (
     BellatorIE,
 from .spiegel import SpiegelIE
 from .spike import (
     BellatorIE,
     StoryFireSeriesIE,
 )
 from .streamable import StreamableIE
     StoryFireSeriesIE,
 )
 from .streamable import StreamableIE
-from .streamcloud import StreamcloudIE
 from .streamcz import StreamCZIE
 from .streamff import StreamFFIE
 from .streetvoice import StreetVoiceIE
 from .streamcz import StreamCZIE
 from .streamff import StreamFFIE
 from .streetvoice import StreetVoiceIE
     SVTSeriesIE,
 )
 from .swearnet import SwearnetEpisodeIE
     SVTSeriesIE,
 )
 from .swearnet import SwearnetEpisodeIE
-from .swrmediathek import SWRMediathekIE
 from .syvdk import SYVDKIE
 from .syfy import SyfyIE
 from .sztvhu import SztvHuIE
 from .syvdk import SYVDKIE
 from .syfy import SyfyIE
 from .sztvhu import SztvHuIE
     ConanClassicIE,
 )
 from .teamtreehouse import TeamTreeHouseIE
     ConanClassicIE,
 )
 from .teamtreehouse import TeamTreeHouseIE
-from .techtalks import TechTalksIE
 from .ted import (
     TedEmbedIE,
     TedPlaylistIE,
 from .ted import (
     TedEmbedIE,
     TedPlaylistIE,
     TikTokLiveIE,
     DouyinIE,
 )
     TikTokLiveIE,
     DouyinIE,
 )
-from .tinypic import TinyPicIE
 from .tmz import TMZIE
 from .tnaflix import (
     TNAFlixNetworkEmbedIE,
 from .tmz import TMZIE
 from .tnaflix import (
     TNAFlixNetworkEmbedIE,
 from .toggo import (
     ToggoIE,
 )
 from .toggo import (
     ToggoIE,
 )
-from .tokentube import (
-    TokentubeIE,
-    TokentubeChannelIE
-)
 from .tonline import TOnlineIE
 from .toongoggles import ToonGogglesIE
 from .toutv import TouTvIE
 from .tonline import TOnlineIE
 from .toongoggles import ToonGogglesIE
 from .toutv import TouTvIE
     TrillerUserIE,
     TrillerShortIE,
 )
     TrillerUserIE,
     TrillerShortIE,
 )
-from .trilulilu import TriluliluIE
 from .trovo import (
     TrovoIE,
     TrovoVodIE,
 from .trovo import (
     TrovoIE,
     TrovoVodIE,
     TuneInPodcastEpisodeIE,
     TuneInShortenerIE,
 )
     TuneInPodcastEpisodeIE,
     TuneInShortenerIE,
 )
-from .tunepk import TunePkIE
 from .turbo import TurboIE
 from .tv2 import (
     TV2IE,
 from .turbo import TurboIE
 from .tv2 import (
     TV2IE,
 from .tviplayer import TVIPlayerIE
 from .tvland import TVLandIE
 from .tvn24 import TVN24IE
 from .tviplayer import TVIPlayerIE
 from .tvland import TVLandIE
 from .tvn24 import TVN24IE
-from .tvnet import TVNetIE
 from .tvnoe import TVNoeIE
 from .tvnoe import TVNoeIE
-from .tvnow import (
-    TVNowIE,
-    TVNowFilmIE,
-    TVNowNewIE,
-    TVNowSeasonIE,
-    TVNowAnnualIE,
-    TVNowShowIE,
-)
 from .tvopengr import (
     TVOpenGrWatchIE,
     TVOpenGrEmbedIE,
 from .tvopengr import (
     TVOpenGrWatchIE,
     TVOpenGrEmbedIE,
 )
 from .tvplayer import TVPlayerIE
 from .tweakers import TweakersIE
 )
 from .tvplayer import TVPlayerIE
 from .tweakers import TweakersIE
-from .twentyfourvideo import TwentyFourVideoIE
 from .twentymin import TwentyMinutenIE
 from .twentythreevideo import TwentyThreeVideoIE
 from .twitcasting import (
 from .twentymin import TwentyMinutenIE
 from .twentythreevideo import TwentyThreeVideoIE
 from .twitcasting import (
 from .umg import UMGDeIE
 from .unistra import UnistraIE
 from .unity import UnityIE
 from .umg import UMGDeIE
 from .unistra import UnistraIE
 from .unity import UnityIE
-from .unscripted import UnscriptedNewsVideoIE
 from .unsupported import KnownDRMIE, KnownPiracyIE
 from .uol import UOLIE
 from .uplynk import (
 from .unsupported import KnownDRMIE, KnownPiracyIE
 from .uol import UOLIE
 from .uplynk import (
 from .utreon import UtreonIE
 from .varzesh3 import Varzesh3IE
 from .vbox7 import Vbox7IE
 from .utreon import UtreonIE
 from .varzesh3 import Varzesh3IE
 from .vbox7 import Vbox7IE
-from .veehd import VeeHDIE
 from .veo import VeoIE
 from .veoh import (
     VeohIE,
 from .veo import VeoIE
 from .veoh import (
     VeohIE,
     ViceArticleIE,
     ViceShowIE,
 )
     ViceArticleIE,
     ViceShowIE,
 )
-from .vidbit import VidbitIE
 from .viddler import ViddlerIE
 from .videa import VideaIE
 from .videocampus_sachsen import (
 from .viddler import ViddlerIE
 from .videa import VideaIE
 from .videocampus_sachsen import (
     VimmIE,
     VimmRecordingIE,
 )
     VimmIE,
     VimmRecordingIE,
 )
-from .vimple import VimpleIE
 from .vine import (
     VineIE,
     VineUserIE,
 from .vine import (
     VineIE,
     VineUserIE,
     VKPlayLiveIE,
 )
 from .vocaroo import VocarooIE
     VKPlayLiveIE,
 )
 from .vocaroo import VocarooIE
-from .vodlocker import VodlockerIE
 from .vodpl import VODPlIE
 from .vodplatform import VODPlatformIE
 from .vodpl import VODPlIE
 from .vodplatform import VODPlatformIE
-from .voicerepublic import VoiceRepublicIE
 from .voicy import (
     VoicyIE,
     VoicyChannelIE,
 from .voicy import (
     VoicyIE,
     VoicyChannelIE,
     KetnetIE,
     DagelijkseKostIE,
 )
     KetnetIE,
     DagelijkseKostIE,
 )
-from .vrak import VrakIE
-from .vrv import (
-    VRVIE,
-    VRVSeriesIE,
-)
-from .vshare import VShareIE
 from .vtm import VTMIE
 from .medialaan import MedialaanIE
 from .vuclip import VuClipIE
 from .vtm import VTMIE
 from .medialaan import MedialaanIE
 from .vuclip import VuClipIE
-from .vupload import VuploadIE
 from .vvvvid import (
     VVVVIDIE,
     VVVVIDShowIE,
 )
 from .vvvvid import (
     VVVVIDIE,
     VVVVIDShowIE,
 )
-from .vyborymos import VyboryMosIE
-from .vzaar import VzaarIE
-from .wakanim import WakanimIE
 from .walla import WallaIE
 from .washingtonpost import (
     WashingtonPostIE,
 from .walla import WallaIE
 from .washingtonpost import (
     WashingtonPostIE,
     WASDTVClipIE,
 )
 from .wat import WatIE
     WASDTVClipIE,
 )
 from .wat import WatIE
-from .watchbox import WatchBoxIE
-from .watchindianporn import WatchIndianPornIE
 from .wdr import (
     WDRIE,
     WDRPageIE,
 from .wdr import (
     WDRIE,
     WDRPageIE,
 from .weyyak import WeyyakIE
 from .whyp import WhypIE
 from .wikimedia import WikimediaIE
 from .weyyak import WeyyakIE
 from .whyp import WhypIE
 from .wikimedia import WikimediaIE
-from .willow import WillowIE
 from .wimbledon import WimbledonIE
 from .wimtv import WimTVIE
 from .whowatch import WhoWatchIE
 from .wimbledon import WimbledonIE
 from .wimtv import WimTVIE
 from .whowatch import WhoWatchIE
     WykopPostCommentIE,
 )
 from .xanimu import XanimuIE
     WykopPostCommentIE,
 )
 from .xanimu import XanimuIE
-from .xbef import XBefIE
 from .xboxclips import XboxClipsIE
 from .xfileshare import XFileShareIE
 from .xhamster import (
 from .xboxclips import XboxClipsIE
 from .xfileshare import XFileShareIE
 from .xhamster import (
 from .xminus import XMinusIE
 from .xnxx import XNXXIE
 from .xstream import XstreamIE
 from .xminus import XMinusIE
 from .xnxx import XNXXIE
 from .xstream import XstreamIE
-from .xtube import XTubeUserIE, XTubeIE
-from .xuite import XuiteIE
 from .xvideos import (
     XVideosIE,
     XVideosQuickiesIE
 from .xvideos import (
     XVideosIE,
     XVideosQuickiesIE
     YappyIE,
     YappyProfileIE,
 )
     YappyIE,
     YappyProfileIE,
 )
-from .yesjapan import YesJapanIE
-from .yinyuetai import YinYueTaiIE
 from .yle_areena import YleAreenaIE
 from .yle_areena import YleAreenaIE
-from .ynet import YnetIE
 from .youjizz import YouJizzIE
 from .youku import (
     YoukuIE,
 from .youjizz import YouJizzIE
 from .youku import (
     YoukuIE,
diff --git a/yt_dlp/extractor/airmozilla.py b/yt_dlp/extractor/airmozilla.py
deleted file mode 100644 (file)
index 669556b..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..utils import (
-    int_or_none,
-    parse_duration,
-    parse_iso8601,
-)
-
-
-class AirMozillaIE(InfoExtractor):
-    _VALID_URL = r'https?://air\.mozilla\.org/(?P<id>[0-9a-z-]+)/?'
-    _TEST = {
-        'url': 'https://air.mozilla.org/privacy-lab-a-meetup-for-privacy-minded-people-in-san-francisco/',
-        'md5': '8d02f53ee39cf006009180e21df1f3ba',
-        'info_dict': {
-            'id': '6x4q2w',
-            'ext': 'mp4',
-            'title': 'Privacy Lab - a meetup for privacy minded people in San Francisco',
-            'thumbnail': r're:https?://.*/poster\.jpg',
-            'description': 'Brings together privacy professionals and others interested in privacy at for-profits, non-profits, and NGOs in an effort to contribute to the state of the ecosystem...',
-            'timestamp': 1422487800,
-            'upload_date': '20150128',
-            'location': 'SFO Commons',
-            'duration': 3780,
-            'view_count': int,
-            'categories': ['Main', 'Privacy'],
-        }
-    }
-
-    def _real_extract(self, url):
-        display_id = self._match_id(url)
-        webpage = self._download_webpage(url, display_id)
-        video_id = self._html_search_regex(r'//vid\.ly/(.*?)/embed', webpage, 'id')
-
-        embed_script = self._download_webpage('https://vid.ly/{0}/embed'.format(video_id), video_id)
-        jwconfig = self._parse_json(self._search_regex(
-            r'initCallback\((.*)\);', embed_script, 'metadata'), video_id)['config']
-
-        info_dict = self._parse_jwplayer_data(jwconfig, video_id)
-        view_count = int_or_none(self._html_search_regex(
-            r'Views since archived: ([0-9]+)',
-            webpage, 'view count', fatal=False))
-        timestamp = parse_iso8601(self._html_search_regex(
-            r'<time datetime="(.*?)"', webpage, 'timestamp', fatal=False))
-        duration = parse_duration(self._search_regex(
-            r'Duration:\s*(\d+\s*hours?\s*\d+\s*minutes?)',
-            webpage, 'duration', fatal=False))
-
-        info_dict.update({
-            'id': video_id,
-            'title': self._og_search_title(webpage),
-            'url': self._og_search_url(webpage),
-            'display_id': display_id,
-            'description': self._og_search_description(webpage),
-            'timestamp': timestamp,
-            'location': self._html_search_regex(r'Location: (.*)', webpage, 'location', default=None),
-            'duration': duration,
-            'view_count': view_count,
-            'categories': re.findall(r'<a href=".*?" class="channel">(.*?)</a>', webpage),
-        })
-
-        return info_dict
index 6949ca9740349d76f57f2675d0662835c4981ba4..455f66795bc72f26830ec99e04dbdd1729832786 100644 (file)
@@ -10,6 +10,7 @@
 
 
 class AolIE(YahooIE):  # XXX: Do not subclass from concrete IE
 
 
 class AolIE(YahooIE):  # XXX: Do not subclass from concrete IE
+    _WORKING = False
     IE_NAME = 'aol.com'
     _VALID_URL = r'(?:aol-video:|https?://(?:www\.)?aol\.(?:com|ca|co\.uk|de|jp)/video/(?:[^/]+/)*)(?P<id>\d{9}|[0-9a-f]{24}|[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12})'
 
     IE_NAME = 'aol.com'
     _VALID_URL = r'(?:aol-video:|https?://(?:www\.)?aol\.(?:com|ca|co\.uk|de|jp)/video/(?:[^/]+/)*)(?P<id>\d{9}|[0-9a-f]{24}|[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12})'
 
diff --git a/yt_dlp/extractor/atttechchannel.py b/yt_dlp/extractor/atttechchannel.py
deleted file mode 100644 (file)
index 6ff4ec0..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-from .common import InfoExtractor
-from ..utils import unified_strdate
-
-
-class ATTTechChannelIE(InfoExtractor):
-    _VALID_URL = r'https?://techchannel\.att\.com/play-video\.cfm/([^/]+/)*(?P<id>.+)'
-    _TEST = {
-        'url': 'http://techchannel.att.com/play-video.cfm/2014/1/27/ATT-Archives-The-UNIX-System-Making-Computers-Easier-to-Use',
-        'info_dict': {
-            'id': '11316',
-            'display_id': 'ATT-Archives-The-UNIX-System-Making-Computers-Easier-to-Use',
-            'ext': 'flv',
-            'title': 'AT&T Archives : The UNIX System: Making Computers Easier to Use',
-            'description': 'A 1982 film about UNIX is the foundation for software in use around Bell Labs and AT&T.',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'upload_date': '20140127',
-        },
-        'params': {
-            # rtmp download
-            'skip_download': True,
-        },
-    }
-
-    def _real_extract(self, url):
-        display_id = self._match_id(url)
-
-        webpage = self._download_webpage(url, display_id)
-
-        video_url = self._search_regex(
-            r"url\s*:\s*'(rtmp://[^']+)'",
-            webpage, 'video URL')
-
-        video_id = self._search_regex(
-            r'mediaid\s*=\s*(\d+)',
-            webpage, 'video id', fatal=False)
-
-        title = self._og_search_title(webpage)
-        description = self._og_search_description(webpage)
-        thumbnail = self._og_search_thumbnail(webpage)
-        upload_date = unified_strdate(self._search_regex(
-            r'[Rr]elease\s+date:\s*(\d{1,2}/\d{1,2}/\d{4})',
-            webpage, 'upload date', fatal=False), False)
-
-        return {
-            'id': video_id,
-            'display_id': display_id,
-            'url': video_url,
-            'ext': 'flv',
-            'title': title,
-            'description': description,
-            'thumbnail': thumbnail,
-            'upload_date': upload_date,
-        }
index ca4498150ee1097b6c06eb3f5ef24fbf2780e517..9d2324f4f4e924f91c061f2685a413ed232f95c8 100644 (file)
@@ -3,6 +3,7 @@
 
 
 class BehindKinkIE(InfoExtractor):
 
 
 class BehindKinkIE(InfoExtractor):
+    _WORKING = False
     _VALID_URL = r'https?://(?:www\.)?behindkink\.com/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/(?P<id>[^/#?_]+)'
     _TEST = {
         'url': 'http://www.behindkink.com/2014/12/05/what-are-you-passionate-about-marley-blaze/',
     _VALID_URL = r'https?://(?:www\.)?behindkink\.com/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/(?P<day>[0-9]{2})/(?P<id>[^/#?_]+)'
     _TEST = {
         'url': 'http://www.behindkink.com/2014/12/05/what-are-you-passionate-about-marley-blaze/',
index 6b867d135f834cc86928f7c086adb0ea8b9edcdc..cbf3dd0824e733186f6032cd7a81a1f7faa64225 100644 (file)
@@ -1,10 +1,9 @@
 from .mtv import MTVServicesInfoExtractor
 from ..utils import unified_strdate
 
 from .mtv import MTVServicesInfoExtractor
 from ..utils import unified_strdate
 
-# TODO Remove - Reason: Outdated Site
-
 
 class BetIE(MTVServicesInfoExtractor):
 
 class BetIE(MTVServicesInfoExtractor):
+    _WORKING = False
     _VALID_URL = r'https?://(?:www\.)?bet\.com/(?:[^/]+/)+(?P<id>.+?)\.html'
     _TESTS = [
         {
     _VALID_URL = r'https?://(?:www\.)?bet\.com/(?:[^/]+/)+(?P<id>.+?)\.html'
     _TESTS = [
         {
index 76f0516a4dcd1866ea79eb15bf9e166590b63c1a..a6ebfedffd1e8648ba49e5ccc83bbf91f77355a5 100644 (file)
@@ -5,6 +5,7 @@
 
 
 class BFIPlayerIE(InfoExtractor):
 
 
 class BFIPlayerIE(InfoExtractor):
+    _WORKING = False
     IE_NAME = 'bfi:player'
     _VALID_URL = r'https?://player\.bfi\.org\.uk/[^/]+/film/watch-(?P<id>[\w-]+)-online'
     _TEST = {
     IE_NAME = 'bfi:player'
     _VALID_URL = r'https?://player\.bfi\.org\.uk/[^/]+/film/watch-(?P<id>[\w-]+)-online'
     _TEST = {
diff --git a/yt_dlp/extractor/biqle.py b/yt_dlp/extractor/biqle.py
deleted file mode 100644 (file)
index 0277535..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-from .common import InfoExtractor
-from .vk import VKIE
-from ..compat import compat_b64decode
-from ..utils import (
-    int_or_none,
-    js_to_json,
-    traverse_obj,
-    unified_timestamp,
-)
-
-
-class BIQLEIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?biqle\.(?:com|org|ru)/watch/(?P<id>-?\d+_\d+)'
-    _TESTS = [{
-        'url': 'https://biqle.ru/watch/-2000421746_85421746',
-        'md5': 'ae6ef4f04d19ac84e4658046d02c151c',
-        'info_dict': {
-            'id': '-2000421746_85421746',
-            'ext': 'mp4',
-            'title': 'Forsaken By Hope Studio Clip',
-            'description': 'Forsaken By Hope Studio Clip — Смотреть онлайн',
-            'upload_date': '19700101',
-            'thumbnail': r're:https://[^/]+/impf/7vN3ACwSTgChP96OdOfzFjUCzFR6ZglDQgWsIw/KPaACiVJJxM\.jpg\?size=800x450&quality=96&keep_aspect_ratio=1&background=000000&sign=b48ea459c4d33dbcba5e26d63574b1cb&type=video_thumb',
-            'timestamp': 0,
-        },
-    }, {
-        'url': 'http://biqle.org/watch/-44781847_168547604',
-        'md5': '7f24e72af1db0edf7c1aaba513174f97',
-        'info_dict': {
-            'id': '-44781847_168547604',
-            'ext': 'mp4',
-            'title': 'Ребенок в шоке от автоматической мойки',
-            'description': 'Ребенок в шоке от автоматической мойки — Смотреть онлайн',
-            'timestamp': 1396633454,
-            'upload_date': '20140404',
-            'thumbnail': r're:https://[^/]+/c535507/u190034692/video/l_b84df002\.jpg',
-        },
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-
-        title = self._html_search_meta('name', webpage, 'Title', fatal=False)
-        timestamp = unified_timestamp(self._html_search_meta('uploadDate', webpage, 'Upload Date', default=None))
-        description = self._html_search_meta('description', webpage, 'Description', default=None)
-
-        global_embed_url = self._search_regex(
-            r'<script[^<]+?window.globEmbedUrl\s*=\s*\'((?:https?:)?//(?:daxab\.com|dxb\.to|[^/]+/player)/[^\']+)\'',
-            webpage, 'global Embed url')
-        hash = self._search_regex(
-            r'<script id="data-embed-video[^<]+?hash: "([^"]+)"[^<]*</script>', webpage, 'Hash')
-
-        embed_url = global_embed_url + hash
-
-        if VKIE.suitable(embed_url):
-            return self.url_result(embed_url, VKIE.ie_key(), video_id)
-
-        embed_page = self._download_webpage(
-            embed_url, video_id, 'Downloading embed webpage', headers={'Referer': url})
-
-        glob_params = self._parse_json(self._search_regex(
-            r'<script id="globParams">[^<]*window.globParams = ([^;]+);[^<]+</script>',
-            embed_page, 'Global Parameters'), video_id, transform_source=js_to_json)
-        host_name = compat_b64decode(glob_params['server'][::-1]).decode()
-
-        item = self._download_json(
-            f'https://{host_name}/method/video.get/{video_id}', video_id,
-            headers={'Referer': url}, query={
-                'token': glob_params['video']['access_token'],
-                'videos': video_id,
-                'ckey': glob_params['c_key'],
-                'credentials': glob_params['video']['credentials'],
-            })['response']['items'][0]
-
-        formats = []
-        for f_id, f_url in item.get('files', {}).items():
-            if f_id == 'external':
-                return self.url_result(f_url)
-            ext, height = f_id.split('_')
-            height_extra_key = traverse_obj(glob_params, ('video', 'partial', 'quality', height))
-            if height_extra_key:
-                formats.append({
-                    'format_id': f'{height}p',
-                    'url': f'https://{host_name}/{f_url[8:]}&videos={video_id}&extra_key={height_extra_key}',
-                    'height': int_or_none(height),
-                    'ext': ext,
-                })
-
-        thumbnails = []
-        for k, v in item.items():
-            if k.startswith('photo_') and v:
-                width = k.replace('photo_', '')
-                thumbnails.append({
-                    'id': width,
-                    'url': v,
-                    'width': int_or_none(width),
-                })
-
-        return {
-            'id': video_id,
-            'title': title,
-            'formats': formats,
-            'comment_count': int_or_none(item.get('comments')),
-            'description': description,
-            'duration': int_or_none(item.get('duration')),
-            'thumbnails': thumbnails,
-            'timestamp': timestamp,
-            'view_count': int_or_none(item.get('views')),
-        }
diff --git a/yt_dlp/extractor/bitwave.py b/yt_dlp/extractor/bitwave.py
deleted file mode 100644 (file)
index a82cd26..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-from .common import InfoExtractor
-
-
-class BitwaveReplayIE(InfoExtractor):
-    IE_NAME = 'bitwave:replay'
-    _VALID_URL = r'https?://(?:www\.)?bitwave\.tv/(?P<user>\w+)/replay/(?P<id>\w+)/?$'
-    _TEST = {
-        'url': 'https://bitwave.tv/RhythmicCarnage/replay/z4P6eq5L7WDrM85UCrVr',
-        'only_matching': True
-    }
-
-    def _real_extract(self, url):
-        replay_id = self._match_id(url)
-        replay = self._download_json(
-            'https://api.bitwave.tv/v1/replays/' + replay_id,
-            replay_id
-        )
-
-        return {
-            'id': replay_id,
-            'title': replay['data']['title'],
-            'uploader': replay['data']['name'],
-            'uploader_id': replay['data']['name'],
-            'url': replay['data']['url'],
-            'thumbnails': [
-                {'url': x} for x in replay['data']['thumbnails']
-            ],
-        }
-
-
-class BitwaveStreamIE(InfoExtractor):
-    IE_NAME = 'bitwave:stream'
-    _VALID_URL = r'https?://(?:www\.)?bitwave\.tv/(?P<id>\w+)/?$'
-    _TEST = {
-        'url': 'https://bitwave.tv/doomtube',
-        'only_matching': True
-    }
-
-    def _real_extract(self, url):
-        username = self._match_id(url)
-        channel = self._download_json(
-            'https://api.bitwave.tv/v1/channels/' + username,
-            username)
-
-        formats = self._extract_m3u8_formats(
-            channel['data']['url'], username,
-            'mp4')
-
-        return {
-            'id': username,
-            'title': channel['data']['title'],
-            'uploader': username,
-            'uploader_id': username,
-            'formats': formats,
-            'thumbnail': channel['data']['thumbnail'],
-            'is_live': True,
-            'view_count': channel['data']['viewCount']
-        }
index 8d8fabe331792e717fe8b8649d4436a56ab4528f..5e5155af26bd2c67561cc9b7681b901fdecc260e 100644 (file)
@@ -22,7 +22,7 @@ class BleacherReportIE(InfoExtractor):
             'upload_date': '20150615',
             'uploader': 'Team Stream Now ',
         },
             'upload_date': '20150615',
             'uploader': 'Team Stream Now ',
         },
-        'add_ie': ['Ooyala'],
+        'skip': 'Video removed',
     }, {
         'url': 'http://bleacherreport.com/articles/2586817-aussie-golfers-get-fright-of-their-lives-after-being-chased-by-angry-kangaroo',
         'md5': '6a5cd403418c7b01719248ca97fb0692',
     }, {
         'url': 'http://bleacherreport.com/articles/2586817-aussie-golfers-get-fright-of-their-lives-after-being-chased-by-angry-kangaroo',
         'md5': '6a5cd403418c7b01719248ca97fb0692',
@@ -70,8 +70,6 @@ def _real_extract(self, url):
             video_type = video['type']
             if video_type in ('cms.bleacherreport.com', 'vid.bleacherreport.com'):
                 info['url'] = 'http://bleacherreport.com/video_embed?id=%s' % video['id']
             video_type = video['type']
             if video_type in ('cms.bleacherreport.com', 'vid.bleacherreport.com'):
                 info['url'] = 'http://bleacherreport.com/video_embed?id=%s' % video['id']
-            elif video_type == 'ooyala.com':
-                info['url'] = 'ooyala:%s' % video['id']
             elif video_type == 'youtube.com':
                 info['url'] = video['id']
             elif video_type == 'vine.co':
             elif video_type == 'youtube.com':
                 info['url'] = video['id']
             elif video_type == 'vine.co':
index 309452d23ec7a752d912ce1478b519b8c9c33720..6e1c63e2bb600bdaa6ee0a52c07a0eafdf93af30 100644 (file)
@@ -1,18 +1,15 @@
-import json
-
 from .common import InfoExtractor
 from ..utils import (
 from .common import InfoExtractor
 from ..utils import (
-    determine_ext,
     ExtractorError,
     int_or_none,
     parse_duration,
     ExtractorError,
     int_or_none,
     parse_duration,
-    parse_iso8601,
     xpath_element,
     xpath_text,
 )
 
 
 class BRIE(InfoExtractor):
     xpath_element,
     xpath_text,
 )
 
 
 class BRIE(InfoExtractor):
+    _WORKING = False
     IE_DESC = 'Bayerischer Rundfunk'
     _VALID_URL = r'(?P<base_url>https?://(?:www\.)?br(?:-klassik)?\.de)/(?:[a-z0-9\-_]+/)+(?P<id>[a-z0-9\-_]+)\.html'
 
     IE_DESC = 'Bayerischer Rundfunk'
     _VALID_URL = r'(?P<base_url>https?://(?:www\.)?br(?:-klassik)?\.de)/(?:[a-z0-9\-_]+/)+(?P<id>[a-z0-9\-_]+)\.html'
 
@@ -167,142 +164,3 @@ def _extract_thumbnails(self, variants, base_url):
         } for variant in variants.findall('variant') if xpath_text(variant, 'url')]
         thumbnails.sort(key=lambda x: x['width'] * x['height'], reverse=True)
         return thumbnails
         } for variant in variants.findall('variant') if xpath_text(variant, 'url')]
         thumbnails.sort(key=lambda x: x['width'] * x['height'], reverse=True)
         return thumbnails
-
-
-class BRMediathekIE(InfoExtractor):
-    IE_DESC = 'Bayerischer Rundfunk Mediathek'
-    _VALID_URL = r'https?://(?:www\.)?br\.de/mediathek//?video/(?:[^/?&#]+?-)?(?P<id>av:[0-9a-f]{24})'
-
-    _TESTS = [{
-        'url': 'https://www.br.de/mediathek/video/gesundheit-die-sendung-vom-28112017-av:5a1e6a6e8fce6d001871cc8e',
-        'md5': 'fdc3d485835966d1622587d08ba632ec',
-        'info_dict': {
-            'id': 'av:5a1e6a6e8fce6d001871cc8e',
-            'ext': 'mp4',
-            'title': 'Die Sendung vom 28.11.2017',
-            'description': 'md5:6000cdca5912ab2277e5b7339f201ccc',
-            'timestamp': 1511942766,
-            'upload_date': '20171129',
-        }
-    }, {
-        'url': 'https://www.br.de/mediathek//video/av:61b0db581aed360007558c12',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        clip_id = self._match_id(url)
-
-        clip = self._download_json(
-            'https://proxy-base.master.mango.express/graphql',
-            clip_id, data=json.dumps({
-                "query": """{
-  viewer {
-    clip(id: "%s") {
-      title
-      description
-      duration
-      createdAt
-      ageRestriction
-      videoFiles {
-        edges {
-          node {
-            publicLocation
-            fileSize
-            videoProfile {
-              width
-              height
-              bitrate
-              encoding
-            }
-          }
-        }
-      }
-      captionFiles {
-        edges {
-          node {
-            publicLocation
-          }
-        }
-      }
-      teaserImages {
-        edges {
-          node {
-            imageFiles {
-              edges {
-                node {
-                  publicLocation
-                  width
-                  height
-                }
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}""" % clip_id}).encode(), headers={
-                'Content-Type': 'application/json',
-            })['data']['viewer']['clip']
-        title = clip['title']
-
-        formats = []
-        for edge in clip.get('videoFiles', {}).get('edges', []):
-            node = edge.get('node', {})
-            n_url = node.get('publicLocation')
-            if not n_url:
-                continue
-            ext = determine_ext(n_url)
-            if ext == 'm3u8':
-                formats.extend(self._extract_m3u8_formats(
-                    n_url, clip_id, 'mp4', 'm3u8_native',
-                    m3u8_id='hls', fatal=False))
-            else:
-                video_profile = node.get('videoProfile', {})
-                tbr = int_or_none(video_profile.get('bitrate'))
-                format_id = 'http'
-                if tbr:
-                    format_id += '-%d' % tbr
-                formats.append({
-                    'format_id': format_id,
-                    'url': n_url,
-                    'width': int_or_none(video_profile.get('width')),
-                    'height': int_or_none(video_profile.get('height')),
-                    'tbr': tbr,
-                    'filesize': int_or_none(node.get('fileSize')),
-                })
-
-        subtitles = {}
-        for edge in clip.get('captionFiles', {}).get('edges', []):
-            node = edge.get('node', {})
-            n_url = node.get('publicLocation')
-            if not n_url:
-                continue
-            subtitles.setdefault('de', []).append({
-                'url': n_url,
-            })
-
-        thumbnails = []
-        for edge in clip.get('teaserImages', {}).get('edges', []):
-            for image_edge in edge.get('node', {}).get('imageFiles', {}).get('edges', []):
-                node = image_edge.get('node', {})
-                n_url = node.get('publicLocation')
-                if not n_url:
-                    continue
-                thumbnails.append({
-                    'url': n_url,
-                    'width': int_or_none(node.get('width')),
-                    'height': int_or_none(node.get('height')),
-                })
-
-        return {
-            'id': clip_id,
-            'title': title,
-            'description': clip.get('description'),
-            'duration': int_or_none(clip.get('duration')),
-            'timestamp': parse_iso8601(clip.get('createdAt')),
-            'age_limit': int_or_none(clip.get('ageRestriction')),
-            'formats': formats,
-            'subtitles': subtitles,
-            'thumbnails': thumbnails,
-        }
diff --git a/yt_dlp/extractor/breakcom.py b/yt_dlp/extractor/breakcom.py
deleted file mode 100644 (file)
index 00cf308..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-from .common import InfoExtractor
-from .youtube import YoutubeIE
-from ..utils import (
-    int_or_none,
-    url_or_none,
-)
-
-
-class BreakIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?break\.com/video/(?P<display_id>[^/]+?)(?:-(?P<id>\d+))?(?:[/?#&]|$)'
-    _TESTS = [{
-        'url': 'http://www.break.com/video/when-girls-act-like-guys-2468056',
-        'info_dict': {
-            'id': '2468056',
-            'ext': 'mp4',
-            'title': 'When Girls Act Like D-Bags',
-            'age_limit': 13,
-        },
-    }, {
-        # youtube embed
-        'url': 'http://www.break.com/video/someone-forgot-boat-brakes-work',
-        'info_dict': {
-            'id': 'RrrDLdeL2HQ',
-            'ext': 'mp4',
-            'title': 'Whale Watching Boat Crashing Into San Diego Dock',
-            'description': 'md5:afc1b2772f0a8468be51dd80eb021069',
-            'upload_date': '20160331',
-            'uploader': 'Steve Holden',
-            'uploader_id': 'sdholden07',
-        },
-        'params': {
-            'skip_download': True,
-        }
-    }, {
-        'url': 'http://www.break.com/video/ugc/baby-flex-2773063',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        display_id, video_id = self._match_valid_url(url).groups()
-
-        webpage = self._download_webpage(url, display_id)
-
-        youtube_url = YoutubeIE._extract_url(webpage)
-        if youtube_url:
-            return self.url_result(youtube_url, ie=YoutubeIE.ie_key())
-
-        content = self._parse_json(
-            self._search_regex(
-                r'(?s)content["\']\s*:\s*(\[.+?\])\s*[,\n]', webpage,
-                'content'),
-            display_id)
-
-        formats = []
-        for video in content:
-            video_url = url_or_none(video.get('url'))
-            if not video_url:
-                continue
-            bitrate = int_or_none(self._search_regex(
-                r'(\d+)_kbps', video_url, 'tbr', default=None))
-            formats.append({
-                'url': video_url,
-                'format_id': 'http-%d' % bitrate if bitrate else 'http',
-                'tbr': bitrate,
-            })
-
-        title = self._search_regex(
-            (r'title["\']\s*:\s*(["\'])(?P<value>(?:(?!\1).)+)\1',
-             r'<h1[^>]*>(?P<value>[^<]+)'), webpage, 'title', group='value')
-
-        def get(key, name):
-            return int_or_none(self._search_regex(
-                r'%s["\']\s*:\s*["\'](\d+)' % key, webpage, name,
-                default=None))
-
-        age_limit = get('ratings', 'age limit')
-        video_id = video_id or get('pid', 'video id') or display_id
-
-        return {
-            'id': video_id,
-            'display_id': display_id,
-            'title': title,
-            'thumbnail': self._og_search_thumbnail(webpage),
-            'age_limit': age_limit,
-            'formats': formats,
-        }
index 9ed6efe799475fe3edead12ea3d10b077e18e126..ad35427ed750bda9b49ebc62f90c8e7b1ae63dcb 100644 (file)
@@ -8,9 +8,9 @@
 
 
 class BYUtvIE(InfoExtractor):
 
 
 class BYUtvIE(InfoExtractor):
+    _WORKING = False
     _VALID_URL = r'https?://(?:www\.)?byutv\.org/(?:watch|player)/(?!event/)(?P<id>[0-9a-f-]+)(?:/(?P<display_id>[^/?#&]+))?'
     _TESTS = [{
     _VALID_URL = r'https?://(?:www\.)?byutv\.org/(?:watch|player)/(?!event/)(?P<id>[0-9a-f-]+)(?:/(?P<display_id>[^/?#&]+))?'
     _TESTS = [{
-        # ooyalaVOD
         'url': 'http://www.byutv.org/watch/6587b9a3-89d2-42a6-a7f7-fd2f81840a7d/studio-c-season-5-episode-5',
         'info_dict': {
             'id': 'ZvanRocTpW-G5_yZFeltTAMv6jxOU9KH',
         'url': 'http://www.byutv.org/watch/6587b9a3-89d2-42a6-a7f7-fd2f81840a7d/studio-c-season-5-episode-5',
         'info_dict': {
             'id': 'ZvanRocTpW-G5_yZFeltTAMv6jxOU9KH',
@@ -24,7 +24,6 @@ class BYUtvIE(InfoExtractor):
         'params': {
             'skip_download': True,
         },
         'params': {
             'skip_download': True,
         },
-        'add_ie': ['Ooyala'],
     }, {
         # dvr
         'url': 'https://www.byutv.org/player/8f1dab9b-b243-47c8-b525-3e2d021a3451/byu-softball-pacific-vs-byu-41219---game-2',
     }, {
         # dvr
         'url': 'https://www.byutv.org/player/8f1dab9b-b243-47c8-b525-3e2d021a3451/byu-softball-pacific-vs-byu-41219---game-2',
@@ -63,19 +62,6 @@ def _real_extract(self, url):
                 'x-byutv-platformkey': 'xsaaw9c7y5',
             })
 
                 'x-byutv-platformkey': 'xsaaw9c7y5',
             })
 
-        ep = video.get('ooyalaVOD')
-        if ep:
-            return {
-                '_type': 'url_transparent',
-                'ie_key': 'Ooyala',
-                'url': 'ooyala:%s' % ep['providerId'],
-                'id': video_id,
-                'display_id': display_id,
-                'title': ep.get('title'),
-                'description': ep.get('description'),
-                'thumbnail': ep.get('imageThumbnail'),
-            }
-
         info = {}
         formats = []
         subtitles = {}
         info = {}
         formats = []
         subtitles = {}
diff --git a/yt_dlp/extractor/camwithher.py b/yt_dlp/extractor/camwithher.py
deleted file mode 100644 (file)
index a0b3749..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..utils import (
-    int_or_none,
-    parse_duration,
-    unified_strdate,
-)
-
-
-class CamWithHerIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?camwithher\.tv/view_video\.php\?.*\bviewkey=(?P<id>\w+)'
-
-    _TESTS = [{
-        'url': 'http://camwithher.tv/view_video.php?viewkey=6e9a24e2c0e842e1f177&page=&viewtype=&category=',
-        'info_dict': {
-            'id': '5644',
-            'ext': 'flv',
-            'title': 'Periscope Tease',
-            'description': 'In the clouds teasing on periscope to my favorite song',
-            'duration': 240,
-            'view_count': int,
-            'comment_count': int,
-            'uploader': 'MileenaK',
-            'upload_date': '20160322',
-            'age_limit': 18,
-        },
-        'params': {
-            'skip_download': True,
-        }
-    }, {
-        'url': 'http://camwithher.tv/view_video.php?viewkey=6dfd8b7c97531a459937',
-        'only_matching': True,
-    }, {
-        'url': 'http://camwithher.tv/view_video.php?page=&viewkey=6e9a24e2c0e842e1f177&viewtype=&category=',
-        'only_matching': True,
-    }, {
-        'url': 'http://camwithher.tv/view_video.php?viewkey=b6c3b5bea9515d1a1fc4&page=&viewtype=&category=mv',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        webpage = self._download_webpage(url, video_id)
-
-        flv_id = self._html_search_regex(
-            r'<a[^>]+href=["\']/download/\?v=(\d+)', webpage, 'video id')
-
-        # Video URL construction algorithm is reverse-engineered from cwhplayer.swf
-        rtmp_url = 'rtmp://camwithher.tv/clipshare/%s' % (
-            ('mp4:%s.mp4' % flv_id) if int(flv_id) > 2010 else flv_id)
-
-        title = self._html_search_regex(
-            r'<div[^>]+style="float:left"[^>]*>\s*<h2>(.+?)</h2>', webpage, 'title')
-        description = self._html_search_regex(
-            r'>Description:</span>(.+?)</div>', webpage, 'description', default=None)
-
-        runtime = self._search_regex(
-            r'Runtime\s*:\s*(.+?) \|', webpage, 'duration', default=None)
-        if runtime:
-            runtime = re.sub(r'[\s-]', '', runtime)
-        duration = parse_duration(runtime)
-        view_count = int_or_none(self._search_regex(
-            r'Views\s*:\s*(\d+)', webpage, 'view count', default=None))
-        comment_count = int_or_none(self._search_regex(
-            r'Comments\s*:\s*(\d+)', webpage, 'comment count', default=None))
-
-        uploader = self._search_regex(
-            r'Added by\s*:\s*<a[^>]+>([^<]+)</a>', webpage, 'uploader', default=None)
-        upload_date = unified_strdate(self._search_regex(
-            r'Added on\s*:\s*([\d-]+)', webpage, 'upload date', default=None))
-
-        return {
-            'id': flv_id,
-            'url': rtmp_url,
-            'ext': 'flv',
-            'no_resume': True,
-            'title': title,
-            'description': description,
-            'duration': duration,
-            'view_count': view_count,
-            'comment_count': comment_count,
-            'uploader': uploader,
-            'upload_date': upload_date,
-            'age_limit': 18
-        }
diff --git a/yt_dlp/extractor/carambatv.py b/yt_dlp/extractor/carambatv.py
deleted file mode 100644 (file)
index d6044a3..0000000
+++ /dev/null
@@ -1,105 +0,0 @@
-from .common import InfoExtractor
-from ..compat import compat_str
-from ..utils import (
-    format_field,
-    float_or_none,
-    int_or_none,
-    try_get,
-)
-
-from .videomore import VideomoreIE
-
-
-class CarambaTVIE(InfoExtractor):
-    _VALID_URL = r'(?:carambatv:|https?://video1\.carambatv\.ru/v/)(?P<id>\d+)'
-    _TESTS = [{
-        'url': 'http://video1.carambatv.ru/v/191910501',
-        'md5': '2f4a81b7cfd5ab866ee2d7270cb34a2a',
-        'info_dict': {
-            'id': '191910501',
-            'ext': 'mp4',
-            'title': '[BadComedian] - Разборка в Маниле (Абсолютный обзор)',
-            'thumbnail': r're:^https?://.*\.jpg',
-            'duration': 2678.31,
-        },
-    }, {
-        'url': 'carambatv:191910501',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        video = self._download_json(
-            'http://video1.carambatv.ru/v/%s/videoinfo.js' % video_id,
-            video_id)
-
-        title = video['title']
-
-        base_url = video.get('video') or 'http://video1.carambatv.ru/v/%s/' % video_id
-
-        formats = [{
-            'url': base_url + f['fn'],
-            'height': int_or_none(f.get('height')),
-            'format_id': format_field(f, 'height', '%sp'),
-        } for f in video['qualities'] if f.get('fn')]
-
-        thumbnail = video.get('splash')
-        duration = float_or_none(try_get(
-            video, lambda x: x['annotations'][0]['end_time'], compat_str))
-
-        return {
-            'id': video_id,
-            'title': title,
-            'thumbnail': thumbnail,
-            'duration': duration,
-            'formats': formats,
-        }
-
-
-class CarambaTVPageIE(InfoExtractor):
-    _VALID_URL = r'https?://carambatv\.ru/(?:[^/]+/)+(?P<id>[^/?#&]+)'
-    _TEST = {
-        'url': 'http://carambatv.ru/movie/bad-comedian/razborka-v-manile/',
-        'md5': 'a49fb0ec2ad66503eeb46aac237d3c86',
-        'info_dict': {
-            'id': '475222',
-            'ext': 'flv',
-            'title': '[BadComedian] - Разборка в Маниле (Абсолютный обзор)',
-            'thumbnail': r're:^https?://.*\.jpg',
-            # duration reported by videomore is incorrect
-            'duration': int,
-        },
-        'add_ie': [VideomoreIE.ie_key()],
-    }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        webpage = self._download_webpage(url, video_id)
-
-        videomore_url = VideomoreIE._extract_url(webpage)
-        if not videomore_url:
-            videomore_id = self._search_regex(
-                r'getVMCode\s*\(\s*["\']?(\d+)', webpage, 'videomore id',
-                default=None)
-            if videomore_id:
-                videomore_url = 'videomore:%s' % videomore_id
-        if videomore_url:
-            title = self._og_search_title(webpage)
-            return {
-                '_type': 'url_transparent',
-                'url': videomore_url,
-                'ie_key': VideomoreIE.ie_key(),
-                'title': title,
-            }
-
-        video_url = self._og_search_property('video:iframe', webpage, default=None)
-
-        if not video_url:
-            video_id = self._search_regex(
-                r'(?:video_id|crmb_vuid)\s*[:=]\s*["\']?(\d+)',
-                webpage, 'video id')
-            video_url = 'carambatv:%s' % video_id
-
-        return self.url_result(video_url, CarambaTVIE.ie_key())
diff --git a/yt_dlp/extractor/channel9.py b/yt_dlp/extractor/channel9.py
deleted file mode 100644 (file)
index a884740..0000000
+++ /dev/null
@@ -1,252 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..utils import (
-    clean_html,
-    int_or_none,
-    parse_iso8601,
-    qualities,
-    unescapeHTML,
-)
-
-
-class Channel9IE(InfoExtractor):
-    IE_DESC = 'Channel 9'
-    IE_NAME = 'channel9'
-    _VALID_URL = r'https?://(?:www\.)?(?:channel9\.msdn\.com|s\.ch9\.ms)/(?P<contentpath>.+?)(?P<rss>/RSS)?/?(?:[?#&]|$)'
-    _EMBED_REGEX = [r'<iframe[^>]+src=["\'](?P<url>https?://channel9\.msdn\.com/(?:[^/]+/)+)player\b']
-
-    _TESTS = [{
-        'url': 'http://channel9.msdn.com/Events/TechEd/Australia/2013/KOS002',
-        'md5': '32083d4eaf1946db6d454313f44510ca',
-        'info_dict': {
-            'id': '6c413323-383a-49dc-88f9-a22800cab024',
-            'ext': 'wmv',
-            'title': 'Developer Kick-Off Session: Stuff We Love',
-            'description': 'md5:b80bf9355a503c193aff7ec6cd5a7731',
-            'duration': 4576,
-            'thumbnail': r're:https?://.*\.jpg',
-            'timestamp': 1377717420,
-            'upload_date': '20130828',
-            'session_code': 'KOS002',
-            'session_room': 'Arena 1A',
-            'session_speakers': 'count:5',
-        },
-    }, {
-        'url': 'http://channel9.msdn.com/posts/Self-service-BI-with-Power-BI-nuclear-testing',
-        'md5': 'dcf983ee6acd2088e7188c3cf79b46bc',
-        'info_dict': {
-            'id': 'fe8e435f-bb93-4e01-8e97-a28c01887024',
-            'ext': 'wmv',
-            'title': 'Self-service BI with Power BI - nuclear testing',
-            'description': 'md5:2d17fec927fc91e9e17783b3ecc88f54',
-            'duration': 1540,
-            'thumbnail': r're:https?://.*\.jpg',
-            'timestamp': 1386381991,
-            'upload_date': '20131207',
-            'authors': ['Mike Wilmot'],
-        },
-    }, {
-        # low quality mp4 is best
-        'url': 'https://channel9.msdn.com/Events/CPP/CppCon-2015/Ranges-for-the-Standard-Library',
-        'info_dict': {
-            'id': '33ad69d2-6a4e-4172-83a1-a523013dec76',
-            'ext': 'mp4',
-            'title': 'Ranges for the Standard Library',
-            'description': 'md5:9895e0a9fd80822d2f01c454b8f4a372',
-            'duration': 5646,
-            'thumbnail': r're:https?://.*\.jpg',
-            'upload_date': '20150930',
-            'timestamp': 1443640735,
-        },
-        'params': {
-            'skip_download': True,
-        },
-    }, {
-        'url': 'https://channel9.msdn.com/Events/DEVintersection/DEVintersection-2016/RSS',
-        'info_dict': {
-            'id': 'Events/DEVintersection/DEVintersection-2016',
-            'title': 'DEVintersection 2016 Orlando Sessions',
-        },
-        'playlist_mincount': 14,
-    }, {
-        'url': 'https://channel9.msdn.com/Niners/Splendid22/Queue/76acff796e8f411184b008028e0d492b/RSS',
-        'only_matching': True,
-    }, {
-        'url': 'https://channel9.msdn.com/Events/Speakers/scott-hanselman/RSS?UrlSafeName=scott-hanselman',
-        'only_matching': True,
-    }]
-
-    _RSS_URL = 'http://channel9.msdn.com/%s/RSS'
-
-    def _extract_list(self, video_id, rss_url=None):
-        if not rss_url:
-            rss_url = self._RSS_URL % video_id
-        rss = self._download_xml(rss_url, video_id, 'Downloading RSS')
-        entries = [self.url_result(session_url.text, 'Channel9')
-                   for session_url in rss.findall('./channel/item/link')]
-        title_text = rss.find('./channel/title').text
-        return self.playlist_result(entries, video_id, title_text)
-
-    def _real_extract(self, url):
-        content_path, rss = self._match_valid_url(url).groups()
-
-        if rss:
-            return self._extract_list(content_path, url)
-
-        webpage = self._download_webpage(
-            url, content_path, 'Downloading web page')
-
-        episode_data = self._search_regex(
-            r"data-episode='([^']+)'", webpage, 'episode data', default=None)
-        if episode_data:
-            episode_data = self._parse_json(unescapeHTML(
-                episode_data), content_path)
-            content_id = episode_data['contentId']
-            is_session = '/Sessions(' in episode_data['api']
-            content_url = 'https://channel9.msdn.com/odata' + episode_data['api'] + '?$select=Captions,CommentCount,MediaLengthInSeconds,PublishedDate,Rating,RatingCount,Title,VideoMP4High,VideoMP4Low,VideoMP4Medium,VideoPlayerPreviewImage,VideoWMV,VideoWMVHQ,Views,'
-            if is_session:
-                content_url += 'Code,Description,Room,Slides,Speakers,ZipFile&$expand=Speakers'
-            else:
-                content_url += 'Authors,Body&$expand=Authors'
-            content_data = self._download_json(content_url, content_id)
-            title = content_data['Title']
-
-            QUALITIES = (
-                'mp3',
-                'wmv', 'mp4',
-                'wmv-low', 'mp4-low',
-                'wmv-mid', 'mp4-mid',
-                'wmv-high', 'mp4-high',
-            )
-
-            quality_key = qualities(QUALITIES)
-
-            def quality(quality_id, format_url):
-                return (len(QUALITIES) if '_Source.' in format_url
-                        else quality_key(quality_id))
-
-            formats = []
-            urls = set()
-
-            SITE_QUALITIES = {
-                'MP3': 'mp3',
-                'MP4': 'mp4',
-                'Low Quality WMV': 'wmv-low',
-                'Low Quality MP4': 'mp4-low',
-                'Mid Quality WMV': 'wmv-mid',
-                'Mid Quality MP4': 'mp4-mid',
-                'High Quality WMV': 'wmv-high',
-                'High Quality MP4': 'mp4-high',
-            }
-
-            formats_select = self._search_regex(
-                r'(?s)<select[^>]+name=["\']format[^>]+>(.+?)</select', webpage,
-                'formats select', default=None)
-            if formats_select:
-                for mobj in re.finditer(
-                        r'<option\b[^>]+\bvalue=(["\'])(?P<url>(?:(?!\1).)+)\1[^>]*>\s*(?P<format>[^<]+?)\s*<',
-                        formats_select):
-                    format_url = mobj.group('url')
-                    if format_url in urls:
-                        continue
-                    urls.add(format_url)
-                    format_id = mobj.group('format')
-                    quality_id = SITE_QUALITIES.get(format_id, format_id)
-                    formats.append({
-                        'url': format_url,
-                        'format_id': quality_id,
-                        'quality': quality(quality_id, format_url),
-                        'vcodec': 'none' if quality_id == 'mp3' else None,
-                    })
-
-            API_QUALITIES = {
-                'VideoMP4Low': 'mp4-low',
-                'VideoWMV': 'wmv-mid',
-                'VideoMP4Medium': 'mp4-mid',
-                'VideoMP4High': 'mp4-high',
-                'VideoWMVHQ': 'wmv-hq',
-            }
-
-            for format_id, q in API_QUALITIES.items():
-                q_url = content_data.get(format_id)
-                if not q_url or q_url in urls:
-                    continue
-                urls.add(q_url)
-                formats.append({
-                    'url': q_url,
-                    'format_id': q,
-                    'quality': quality(q, q_url),
-                })
-
-            slides = content_data.get('Slides')
-            zip_file = content_data.get('ZipFile')
-
-            if not formats and not slides and not zip_file:
-                self.raise_no_formats(
-                    'None of recording, slides or zip are available for %s' % content_path)
-
-            subtitles = {}
-            for caption in content_data.get('Captions', []):
-                caption_url = caption.get('Url')
-                if not caption_url:
-                    continue
-                subtitles.setdefault(caption.get('Language', 'en'), []).append({
-                    'url': caption_url,
-                    'ext': 'vtt',
-                })
-
-            common = {
-                'id': content_id,
-                'title': title,
-                'description': clean_html(content_data.get('Description') or content_data.get('Body')),
-                'thumbnail': content_data.get('VideoPlayerPreviewImage'),
-                'duration': int_or_none(content_data.get('MediaLengthInSeconds')),
-                'timestamp': parse_iso8601(content_data.get('PublishedDate')),
-                'avg_rating': int_or_none(content_data.get('Rating')),
-                'rating_count': int_or_none(content_data.get('RatingCount')),
-                'view_count': int_or_none(content_data.get('Views')),
-                'comment_count': int_or_none(content_data.get('CommentCount')),
-                'subtitles': subtitles,
-            }
-            if is_session:
-                speakers = []
-                for s in content_data.get('Speakers', []):
-                    speaker_name = s.get('FullName')
-                    if not speaker_name:
-                        continue
-                    speakers.append(speaker_name)
-
-                common.update({
-                    'session_code': content_data.get('Code'),
-                    'session_room': content_data.get('Room'),
-                    'session_speakers': speakers,
-                })
-            else:
-                authors = []
-                for a in content_data.get('Authors', []):
-                    author_name = a.get('DisplayName')
-                    if not author_name:
-                        continue
-                    authors.append(author_name)
-                common['authors'] = authors
-
-            contents = []
-
-            if slides:
-                d = common.copy()
-                d.update({'title': title + '-Slides', 'url': slides})
-                contents.append(d)
-
-            if zip_file:
-                d = common.copy()
-                d.update({'title': title + '-Zip', 'url': zip_file})
-                contents.append(d)
-
-            if formats:
-                d = common.copy()
-                d.update({'title': title, 'formats': formats})
-                contents.append(d)
-            return self.playlist_result(contents)
-        else:
-            return self._extract_list(content_path)
diff --git a/yt_dlp/extractor/chirbit.py b/yt_dlp/extractor/chirbit.py
deleted file mode 100644 (file)
index 452711d..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..compat import compat_b64decode
-from ..utils import parse_duration
-
-
-class ChirbitIE(InfoExtractor):
-    IE_NAME = 'chirbit'
-    _VALID_URL = r'https?://(?:www\.)?chirb\.it/(?:(?:wp|pl)/|fb_chirbit_player\.swf\?key=)?(?P<id>[\da-zA-Z]+)'
-    _TESTS = [{
-        'url': 'http://chirb.it/be2abG',
-        'info_dict': {
-            'id': 'be2abG',
-            'ext': 'mp3',
-            'title': 'md5:f542ea253f5255240be4da375c6a5d7e',
-            'description': 'md5:f24a4e22a71763e32da5fed59e47c770',
-            'duration': 306,
-            'uploader': 'Gerryaudio',
-        },
-        'params': {
-            'skip_download': True,
-        }
-    }, {
-        'url': 'https://chirb.it/fb_chirbit_player.swf?key=PrIPv5',
-        'only_matching': True,
-    }, {
-        'url': 'https://chirb.it/wp/MN58c2',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        audio_id = self._match_id(url)
-
-        webpage = self._download_webpage(
-            'http://chirb.it/%s' % audio_id, audio_id)
-
-        data_fd = self._search_regex(
-            r'data-fd=(["\'])(?P<url>(?:(?!\1).)+)\1',
-            webpage, 'data fd', group='url')
-
-        # Reverse engineered from https://chirb.it/js/chirbit.player.js (look
-        # for soundURL)
-        audio_url = compat_b64decode(data_fd[::-1]).decode('utf-8')
-
-        title = self._search_regex(
-            r'class=["\']chirbit-title["\'][^>]*>([^<]+)', webpage, 'title')
-        description = self._search_regex(
-            r'<h3>Description</h3>\s*<pre[^>]*>([^<]+)</pre>',
-            webpage, 'description', default=None)
-        duration = parse_duration(self._search_regex(
-            r'class=["\']c-length["\'][^>]*>([^<]+)',
-            webpage, 'duration', fatal=False))
-        uploader = self._search_regex(
-            r'id=["\']chirbit-username["\'][^>]*>([^<]+)',
-            webpage, 'uploader', fatal=False)
-
-        return {
-            'id': audio_id,
-            'url': audio_url,
-            'title': title,
-            'description': description,
-            'duration': duration,
-            'uploader': uploader,
-        }
-
-
-class ChirbitProfileIE(InfoExtractor):
-    IE_NAME = 'chirbit:profile'
-    _VALID_URL = r'https?://(?:www\.)?chirbit\.com/(?:rss/)?(?P<id>[^/]+)'
-    _TEST = {
-        'url': 'http://chirbit.com/ScarletBeauty',
-        'info_dict': {
-            'id': 'ScarletBeauty',
-        },
-        'playlist_mincount': 3,
-    }
-
-    def _real_extract(self, url):
-        profile_id = self._match_id(url)
-
-        webpage = self._download_webpage(url, profile_id)
-
-        entries = [
-            self.url_result(self._proto_relative_url('//chirb.it/' + video_id))
-            for _, video_id in re.findall(r'<input[^>]+id=([\'"])copy-btn-(?P<id>[0-9a-zA-Z]+)\1', webpage)]
-
-        return self.playlist_result(entries, profile_id)
diff --git a/yt_dlp/extractor/cinchcast.py b/yt_dlp/extractor/cinchcast.py
deleted file mode 100644 (file)
index 7a7ea8b..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    unified_strdate,
-    xpath_text,
-)
-
-
-class CinchcastIE(InfoExtractor):
-    _VALID_URL = r'https?://player\.cinchcast\.com/.*?(?:assetId|show_id)=(?P<id>[0-9]+)'
-    _EMBED_REGEX = [r'<iframe[^>]+?src=(["\'])(?P<url>https?://player\.cinchcast\.com/.+?)\1']
-
-    _TESTS = [{
-        'url': 'http://player.cinchcast.com/?show_id=5258197&platformId=1&assetType=single',
-        'info_dict': {
-            'id': '5258197',
-            'ext': 'mp3',
-            'title': 'Train Your Brain to Up Your Game with Coach Mandy',
-            'upload_date': '20130816',
-        },
-    }, {
-        # Actual test is run in generic, look for undergroundwellness
-        'url': 'http://player.cinchcast.com/?platformId=1&#038;assetType=single&#038;assetId=7141703',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        doc = self._download_xml(
-            'http://www.blogtalkradio.com/playerasset/mrss?assetType=single&assetId=%s' % video_id,
-            video_id)
-
-        item = doc.find('.//item')
-        title = xpath_text(item, './title', fatal=True)
-        date_str = xpath_text(
-            item, './{http://developer.longtailvideo.com/trac/}date')
-        upload_date = unified_strdate(date_str, day_first=False)
-        # duration is present but wrong
-        formats = [{
-            'format_id': 'main',
-            'url': item.find('./{http://search.yahoo.com/mrss/}content').attrib['url'],
-        }]
-        backup_url = xpath_text(
-            item, './{http://developer.longtailvideo.com/trac/}backupContent')
-        if backup_url:
-            formats.append({
-                'preference': 2,  # seems to be more reliable
-                'format_id': 'backup',
-                'url': backup_url,
-            })
-
-        return {
-            'id': video_id,
-            'title': title,
-            'upload_date': upload_date,
-            'formats': formats,
-        }
diff --git a/yt_dlp/extractor/clipsyndicate.py b/yt_dlp/extractor/clipsyndicate.py
deleted file mode 100644 (file)
index 6064443..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    find_xpath_attr,
-    fix_xml_ampersands
-)
-
-
-class ClipsyndicateIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:chic|www)\.clipsyndicate\.com/video/play(list/\d+)?/(?P<id>\d+)'
-
-    _TESTS = [{
-        'url': 'http://www.clipsyndicate.com/video/play/4629301/brick_briscoe',
-        'md5': '4d7d549451bad625e0ff3d7bd56d776c',
-        'info_dict': {
-            'id': '4629301',
-            'ext': 'mp4',
-            'title': 'Brick Briscoe',
-            'duration': 612,
-            'thumbnail': r're:^https?://.+\.jpg',
-        },
-    }, {
-        'url': 'http://chic.clipsyndicate.com/video/play/5844117/shark_attack',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        js_player = self._download_webpage(
-            'http://eplayer.clipsyndicate.com/embed/player.js?va_id=%s' % video_id,
-            video_id, 'Downlaoding player')
-        # it includes a required token
-        flvars = self._search_regex(r'flvars: "(.*?)"', js_player, 'flvars')
-
-        pdoc = self._download_xml(
-            'http://eplayer.clipsyndicate.com/osmf/playlist?%s' % flvars,
-            video_id, 'Downloading video info',
-            transform_source=fix_xml_ampersands)
-
-        track_doc = pdoc.find('trackList/track')
-
-        def find_param(name):
-            node = find_xpath_attr(track_doc, './/param', 'name', name)
-            if node is not None:
-                return node.attrib['value']
-
-        return {
-            'id': video_id,
-            'title': find_param('title'),
-            'url': track_doc.find('location').text,
-            'thumbnail': find_param('thumbnail'),
-            'duration': int(find_param('duration')),
-        }
diff --git a/yt_dlp/extractor/cloudy.py b/yt_dlp/extractor/cloudy.py
deleted file mode 100644 (file)
index 848643e..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    str_to_int,
-    unified_strdate,
-)
-
-
-class CloudyIE(InfoExtractor):
-    _IE_DESC = 'cloudy.ec'
-    _VALID_URL = r'https?://(?:www\.)?cloudy\.ec/(?:v/|embed\.php\?.*?\bid=)(?P<id>[A-Za-z0-9]+)'
-    _TESTS = [{
-        'url': 'https://www.cloudy.ec/v/af511e2527aac',
-        'md5': '29832b05028ead1b58be86bf319397ca',
-        'info_dict': {
-            'id': 'af511e2527aac',
-            'ext': 'mp4',
-            'title': 'Funny Cats and Animals Compilation june 2013',
-            'upload_date': '20130913',
-            'view_count': int,
-        }
-    }, {
-        'url': 'http://www.cloudy.ec/embed.php?autoplay=1&id=af511e2527aac',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        webpage = self._download_webpage(
-            'https://www.cloudy.ec/embed.php', video_id, query={
-                'id': video_id,
-                'playerPage': 1,
-                'autoplay': 1,
-            })
-
-        info = self._parse_html5_media_entries(url, webpage, video_id)[0]
-
-        webpage = self._download_webpage(
-            'https://www.cloudy.ec/v/%s' % video_id, video_id, fatal=False)
-
-        if webpage:
-            info.update({
-                'title': self._search_regex(
-                    r'<h\d[^>]*>([^<]+)<', webpage, 'title'),
-                'upload_date': unified_strdate(self._search_regex(
-                    r'>Published at (\d{4}-\d{1,2}-\d{1,2})', webpage,
-                    'upload date', fatal=False)),
-                'view_count': str_to_int(self._search_regex(
-                    r'([\d,.]+) views<', webpage, 'view count', fatal=False)),
-            })
-
-        if not info.get('title'):
-            info['title'] = video_id
-
-        info['id'] = video_id
-
-        return info
index 403e44aafd248dcc71ecc4cd2457e1968e517cfd..716f259694681690492ca428345758b639ae01f5 100644 (file)
@@ -6,6 +6,7 @@
 
 
 class ClubicIE(InfoExtractor):
 
 
 class ClubicIE(InfoExtractor):
+    _WORKING = False
     _VALID_URL = r'https?://(?:www\.)?clubic\.com/video/(?:[^/]+/)*video.*-(?P<id>[0-9]+)\.html'
 
     _TESTS = [{
     _VALID_URL = r'https?://(?:www\.)?clubic\.com/video/(?:[^/]+/)*video.*-(?P<id>[0-9]+)\.html'
 
     _TESTS = [{
index 8aed7708b1632e5d32eba414b154f3525b486262..6359102aa500ed000c5e31f3e34042bac055e8f4 100644 (file)
@@ -4,6 +4,7 @@
 
 
 class CMTIE(MTVIE):  # XXX: Do not subclass from concrete IE
 
 
 class CMTIE(MTVIE):  # XXX: Do not subclass from concrete IE
+    _WORKING = False
     IE_NAME = 'cmt.com'
     _VALID_URL = r'https?://(?:www\.)?cmt\.com/(?:videos|shows|(?:full-)?episodes|video-clips)/(?P<id>[^/]+)'
 
     IE_NAME = 'cmt.com'
     _VALID_URL = r'https?://(?:www\.)?cmt\.com/(?:videos|shows|(?:full-)?episodes|video-clips)/(?P<id>[^/]+)'
 
diff --git a/yt_dlp/extractor/daftsex.py b/yt_dlp/extractor/daftsex.py
deleted file mode 100644 (file)
index 92510c7..0000000
+++ /dev/null
@@ -1,150 +0,0 @@
-from .common import InfoExtractor
-from ..compat import compat_b64decode
-from ..utils import (
-    ExtractorError,
-    int_or_none,
-    js_to_json,
-    parse_count,
-    parse_duration,
-    traverse_obj,
-    try_get,
-    unified_timestamp,
-)
-
-
-class DaftsexIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?daft\.sex/watch/(?P<id>-?\d+_\d+)'
-    _TESTS = [{
-        'url': 'https://daft.sex/watch/-35370899_456246186',
-        'md5': '64c04ef7b4c7b04b308f3b0c78efe7cd',
-        'info_dict': {
-            'id': '-35370899_456246186',
-            'ext': 'mp4',
-            'title': 'just relaxing',
-            'description': 'just relaxing – Watch video Watch video in high quality',
-            'upload_date': '20201113',
-            'timestamp': 1605261911,
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'age_limit': 18,
-            'duration': 15.0,
-            'view_count': int
-        },
-    }, {
-        'url': 'https://daft.sex/watch/-156601359_456242791',
-        'info_dict': {
-            'id': '-156601359_456242791',
-            'ext': 'mp4',
-            'title': 'Skye Blue - Dinner And A Show',
-            'description': 'Skye Blue - Dinner And A Show - Watch video Watch video in high quality',
-            'upload_date': '20200916',
-            'timestamp': 1600250735,
-            'thumbnail': 'https://psv153-1.crazycloud.ru/videos/-156601359/456242791/thumb.jpg?extra=i3D32KaBbBFf9TqDRMAVmQ',
-        },
-        'skip': 'deleted / private'
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-        title = self._html_search_meta('name', webpage, 'title')
-        timestamp = unified_timestamp(self._html_search_meta('uploadDate', webpage, 'Upload Date', default=None))
-        description = self._html_search_meta('description', webpage, 'Description', default=None)
-
-        duration = parse_duration(self._search_regex(
-            r'Duration: ((?:[0-9]{2}:){0,2}[0-9]{2})',
-            webpage, 'duration', fatal=False))
-        views = parse_count(self._search_regex(
-            r'Views: ([0-9 ]+)',
-            webpage, 'views', fatal=False))
-
-        player_hash = self._search_regex(
-            r'DaxabPlayer\.Init\({[\s\S]*hash:\s*"([0-9a-zA-Z_\-]+)"[\s\S]*}',
-            webpage, 'player hash')
-        player_color = self._search_regex(
-            r'DaxabPlayer\.Init\({[\s\S]*color:\s*"([0-9a-z]+)"[\s\S]*}',
-            webpage, 'player color', fatal=False) or ''
-
-        embed_page = self._download_webpage(
-            'https://dxb.to/player/%s?color=%s' % (player_hash, player_color),
-            video_id, headers={'Referer': url})
-        video_params = self._parse_json(
-            self._search_regex(
-                r'window\.globParams\s*=\s*({[\S\s]+})\s*;\s*<\/script>',
-                embed_page, 'video parameters'),
-            video_id, transform_source=js_to_json)
-
-        server_domain = 'https://%s' % compat_b64decode(video_params['server'][::-1]).decode('utf-8')
-
-        cdn_files = traverse_obj(video_params, ('video', 'cdn_files')) or {}
-        if cdn_files:
-            formats = []
-            for format_id, format_data in cdn_files.items():
-                ext, height = format_id.split('_')
-                formats.append({
-                    'format_id': format_id,
-                    'url': f'{server_domain}/videos/{video_id.replace("_", "/")}/{height}.mp4?extra={format_data.split(".")[-1]}',
-                    'height': int_or_none(height),
-                    'ext': ext,
-                })
-
-            return {
-                'id': video_id,
-                'title': title,
-                'formats': formats,
-                'description': description,
-                'duration': duration,
-                'thumbnail': try_get(video_params, lambda vi: 'https:' + compat_b64decode(vi['video']['thumb']).decode('utf-8')),
-                'timestamp': timestamp,
-                'view_count': views,
-                'age_limit': 18,
-            }
-
-        items = self._download_json(
-            f'{server_domain}/method/video.get/{video_id}', video_id,
-            headers={'Referer': url}, query={
-                'token': video_params['video']['access_token'],
-                'videos': video_id,
-                'ckey': video_params['c_key'],
-                'credentials': video_params['video']['credentials'],
-            })['response']['items']
-
-        if not items:
-            raise ExtractorError('Video is not available', video_id=video_id, expected=True)
-
-        item = items[0]
-        formats = []
-        for f_id, f_url in item.get('files', {}).items():
-            if f_id == 'external':
-                return self.url_result(f_url)
-            ext, height = f_id.split('_')
-            height_extra_key = traverse_obj(video_params, ('video', 'partial', 'quality', height))
-            if height_extra_key:
-                formats.append({
-                    'format_id': f'{height}p',
-                    'url': f'{server_domain}/{f_url[8:]}&videos={video_id}&extra_key={height_extra_key}',
-                    'height': int_or_none(height),
-                    'ext': ext,
-                })
-
-        thumbnails = []
-        for k, v in item.items():
-            if k.startswith('photo_') and v:
-                width = k.replace('photo_', '')
-                thumbnails.append({
-                    'id': width,
-                    'url': v,
-                    'width': int_or_none(width),
-                })
-
-        return {
-            'id': video_id,
-            'title': title,
-            'formats': formats,
-            'comment_count': int_or_none(item.get('comments')),
-            'description': description,
-            'duration': duration,
-            'thumbnails': thumbnails,
-            'timestamp': timestamp,
-            'view_count': views,
-            'age_limit': 18,
-        }
diff --git a/yt_dlp/extractor/defense.py b/yt_dlp/extractor/defense.py
deleted file mode 100644 (file)
index 7d73ea8..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-from .common import InfoExtractor
-
-
-class DefenseGouvFrIE(InfoExtractor):
-    IE_NAME = 'defense.gouv.fr'
-    _VALID_URL = r'https?://.*?\.defense\.gouv\.fr/layout/set/ligthboxvideo/base-de-medias/webtv/(?P<id>[^/?#]*)'
-
-    _TEST = {
-        'url': 'http://www.defense.gouv.fr/layout/set/ligthboxvideo/base-de-medias/webtv/attaque-chimique-syrienne-du-21-aout-2013-1',
-        'md5': '75bba6124da7e63d2d60b5244ec9430c',
-        'info_dict': {
-            'id': '11213',
-            'ext': 'mp4',
-            'title': 'attaque-chimique-syrienne-du-21-aout-2013-1'
-        }
-    }
-
-    def _real_extract(self, url):
-        title = self._match_id(url)
-        webpage = self._download_webpage(url, title)
-
-        video_id = self._search_regex(
-            r"flashvars.pvg_id=\"(\d+)\";",
-            webpage, 'ID')
-
-        json_url = (
-            'http://static.videos.gouv.fr/brightcovehub/export/json/%s' %
-            video_id)
-        info = self._download_json(json_url, title, 'Downloading JSON config')
-        video_url = info['renditions'][0]['url']
-
-        return {
-            'id': video_id,
-            'ext': 'mp4',
-            'url': video_url,
-            'title': title,
-        }
index 3d42fc2b0ce20177568eb33e03503784970ece15..a5f5f794cb1f6f8db1fb13510b17e96f017a9f55 100644 (file)
@@ -3,6 +3,7 @@
 
 
 class DHMIE(InfoExtractor):
 
 
 class DHMIE(InfoExtractor):
+    _WORKING = False
     IE_DESC = 'Filmarchiv - Deutsches Historisches Museum'
     _VALID_URL = r'https?://(?:www\.)?dhm\.de/filmarchiv/(?:[^/]+/)+(?P<id>[^/]+)'
 
     IE_DESC = 'Filmarchiv - Deutsches Historisches Museum'
     _VALID_URL = r'https?://(?:www\.)?dhm\.de/filmarchiv/(?:[^/]+/)+(?P<id>[^/]+)'
 
diff --git a/yt_dlp/extractor/dotsub.py b/yt_dlp/extractor/dotsub.py
deleted file mode 100644 (file)
index 079f837..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    float_or_none,
-    int_or_none,
-)
-
-
-class DotsubIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?dotsub\.com/view/(?P<id>[^/]+)'
-    _TESTS = [{
-        'url': 'https://dotsub.com/view/9c63db2a-fa95-4838-8e6e-13deafe47f09',
-        'md5': '21c7ff600f545358134fea762a6d42b6',
-        'info_dict': {
-            'id': '9c63db2a-fa95-4838-8e6e-13deafe47f09',
-            'ext': 'flv',
-            'title': 'MOTIVATION - "It\'s Possible" Best Inspirational Video Ever',
-            'description': 'md5:41af1e273edbbdfe4e216a78b9d34ac6',
-            'thumbnail': 're:^https?://dotsub.com/media/9c63db2a-fa95-4838-8e6e-13deafe47f09/p',
-            'duration': 198,
-            'uploader': 'liuxt',
-            'timestamp': 1385778501.104,
-            'upload_date': '20131130',
-            'view_count': int,
-        }
-    }, {
-        'url': 'https://dotsub.com/view/747bcf58-bd59-45b7-8c8c-ac312d084ee6',
-        'md5': '2bb4a83896434d5c26be868c609429a3',
-        'info_dict': {
-            'id': '168006778',
-            'ext': 'mp4',
-            'title': 'Apartments and flats in Raipur the white symphony',
-            'description': 'md5:784d0639e6b7d1bc29530878508e38fe',
-            'thumbnail': 're:^https?://dotsub.com/media/747bcf58-bd59-45b7-8c8c-ac312d084ee6/p',
-            'duration': 290,
-            'timestamp': 1476767794.2809999,
-            'upload_date': '20161018',
-            'uploader': 'parthivi001',
-            'uploader_id': 'user52596202',
-            'view_count': int,
-        },
-        'add_ie': ['Vimeo'],
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        info = self._download_json(
-            'https://dotsub.com/api/media/%s/metadata' % video_id, video_id)
-        video_url = info.get('mediaURI')
-
-        if not video_url:
-            webpage = self._download_webpage(url, video_id)
-            video_url = self._search_regex(
-                [r'<source[^>]+src="([^"]+)"', r'"file"\s*:\s*\'([^\']+)'],
-                webpage, 'video url', default=None)
-            info_dict = {
-                'id': video_id,
-                'url': video_url,
-                'ext': 'flv',
-            }
-
-        if not video_url:
-            setup_data = self._parse_json(self._html_search_regex(
-                r'(?s)data-setup=([\'"])(?P<content>(?!\1).+?)\1',
-                webpage, 'setup data', group='content'), video_id)
-            info_dict = {
-                '_type': 'url_transparent',
-                'url': setup_data['src'],
-            }
-
-        info_dict.update({
-            'title': info['title'],
-            'description': info.get('description'),
-            'thumbnail': info.get('screenshotURI'),
-            'duration': int_or_none(info.get('duration'), 1000),
-            'uploader': info.get('user'),
-            'timestamp': float_or_none(info.get('dateCreated'), 1000),
-            'view_count': int_or_none(info.get('numberOfViews')),
-        })
-
-        return info_dict
diff --git a/yt_dlp/extractor/echomsk.py b/yt_dlp/extractor/echomsk.py
deleted file mode 100644 (file)
index 850eabb..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-import re
-
-from .common import InfoExtractor
-
-
-class EchoMskIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?echo\.msk\.ru/sounds/(?P<id>\d+)'
-    _TEST = {
-        'url': 'http://www.echo.msk.ru/sounds/1464134.html',
-        'md5': '2e44b3b78daff5b458e4dbc37f191f7c',
-        'info_dict': {
-            'id': '1464134',
-            'ext': 'mp3',
-            'title': 'Особое мнение - 29 декабря 2014, 19:08',
-        },
-    }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        webpage = self._download_webpage(url, video_id)
-
-        audio_url = self._search_regex(
-            r'<a rel="mp3" href="([^"]+)">', webpage, 'audio URL')
-
-        title = self._html_search_regex(
-            r'<a href="/programs/[^"]+" target="_blank">([^<]+)</a>',
-            webpage, 'title')
-
-        air_date = self._html_search_regex(
-            r'(?s)<div class="date">(.+?)</div>',
-            webpage, 'date', fatal=False, default=None)
-
-        if air_date:
-            air_date = re.sub(r'(\s)\1+', r'\1', air_date)
-            if air_date:
-                title = '%s - %s' % (title, air_date)
-
-        return {
-            'id': video_id,
-            'url': audio_url,
-            'title': title,
-        }
diff --git a/yt_dlp/extractor/ehow.py b/yt_dlp/extractor/ehow.py
deleted file mode 100644 (file)
index 74469ce..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-from .common import InfoExtractor
-from ..compat import compat_urllib_parse_unquote
-
-
-class EHowIE(InfoExtractor):
-    IE_NAME = 'eHow'
-    _VALID_URL = r'https?://(?:www\.)?ehow\.com/[^/_?]*_(?P<id>[0-9]+)'
-    _TEST = {
-        'url': 'http://www.ehow.com/video_12245069_hardwood-flooring-basics.html',
-        'md5': '9809b4e3f115ae2088440bcb4efbf371',
-        'info_dict': {
-            'id': '12245069',
-            'ext': 'flv',
-            'title': 'Hardwood Flooring Basics',
-            'description': 'Hardwood flooring may be time consuming, but its ultimately a pretty straightforward concept. Learn about hardwood flooring basics with help from a hardware flooring business owner in this free video...',
-            'uploader': 'Erick Nathan',
-        }
-    }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-        video_url = self._search_regex(
-            r'(?:file|source)=(http[^\'"&]*)', webpage, 'video URL')
-        final_url = compat_urllib_parse_unquote(video_url)
-        uploader = self._html_search_meta('uploader', webpage)
-        title = self._og_search_title(webpage).replace(' | eHow', '')
-
-        return {
-            'id': video_id,
-            'url': final_url,
-            'title': title,
-            'thumbnail': self._og_search_thumbnail(webpage),
-            'description': self._og_search_description(webpage),
-            'uploader': uploader,
-        }
diff --git a/yt_dlp/extractor/elevensports.py b/yt_dlp/extractor/elevensports.py
deleted file mode 100644 (file)
index 99c52b3..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    parse_iso8601,
-    traverse_obj,
-    url_or_none,
-)
-
-
-class ElevenSportsIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?elevensports\.com/view/event/(?P<id>\w+)'
-    _TESTS = [{
-        'url': 'https://elevensports.com/view/event/clf46yr3kenn80jgrqsjmwefk',
-        'md5': 'c0958d9ff90e4503a75544358758921d',
-        'info_dict': {
-            'id': 'clf46yr3kenn80jgrqsjmwefk',
-            'title': 'Cleveland SC vs Lionsbridge FC',
-            'ext': 'mp4',
-            'description': 'md5:03b5238d6549f4ea1fddadf69b5e0b58',
-            'upload_date': '20230323',
-            'timestamp': 1679612400,
-            'thumbnail': r're:^https?://.*\.(?:jpg|png)',
-        },
-        'params': {'skip_download': 'm3u8'}
-    }, {
-        'url': 'https://elevensports.com/view/event/clhpyd53b06160jez74qhgkmf',
-        'md5': 'c0958d9ff90e4503a75544358758921d',
-        'info_dict': {
-            'id': 'clhpyd53b06160jez74qhgkmf',
-            'title': 'AJNLF vs ARRAF',
-            'ext': 'mp4',
-            'description': 'md5:c8c5e75c78f37c6d15cd6c475e43a8c1',
-            'upload_date': '20230521',
-            'timestamp': 1684684800,
-            'thumbnail': r're:^https?://.*\.(?:jpg|png)',
-        },
-        'params': {'skip_download': 'm3u8'}
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-        event_id = self._search_nextjs_data(webpage, video_id)['props']['pageProps']['event']['mclsEventId']
-        event_data = self._download_json(
-            f'https://mcls-api.mycujoo.tv/bff/events/v1beta1/{event_id}', video_id,
-            headers={'Authorization': 'Bearer FBVKACGN37JQC5SFA0OVK8KKSIOP153G'})
-        formats, subtitles = self._extract_m3u8_formats_and_subtitles(
-            event_data['streams'][0]['full_url'], video_id, 'mp4', m3u8_id='hls')
-
-        return {
-            'id': video_id,
-            'formats': formats,
-            'subtitles': subtitles,
-            **traverse_obj(event_data, {
-                'title': ('title', {str}),
-                'description': ('description', {str}),
-                'timestamp': ('start_time', {parse_iso8601}),
-                'thumbnail': ('thumbnail_url', {url_or_none}),
-            }),
-        }
diff --git a/yt_dlp/extractor/ellentube.py b/yt_dlp/extractor/ellentube.py
deleted file mode 100644 (file)
index 6eb00f9..0000000
+++ /dev/null
@@ -1,130 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    clean_html,
-    extract_attributes,
-    float_or_none,
-    int_or_none,
-    try_get,
-)
-
-
-class EllenTubeBaseIE(InfoExtractor):
-    def _extract_data_config(self, webpage, video_id):
-        details = self._search_regex(
-            r'(<[^>]+\bdata-component=(["\'])[Dd]etails.+?></div>)', webpage,
-            'details')
-        return self._parse_json(
-            extract_attributes(details)['data-config'], video_id)
-
-    def _extract_video(self, data, video_id):
-        title = data['title']
-
-        formats = []
-        duration = None
-        for entry in data.get('media'):
-            if entry.get('id') == 'm3u8':
-                formats, subtitles = self._extract_m3u8_formats_and_subtitles(
-                    entry['url'], video_id, 'mp4',
-                    entry_protocol='m3u8_native', m3u8_id='hls')
-                duration = int_or_none(entry.get('duration'))
-                break
-
-        def get_insight(kind):
-            return int_or_none(try_get(
-                data, lambda x: x['insight']['%ss' % kind]))
-
-        return {
-            'extractor_key': EllenTubeIE.ie_key(),
-            'id': video_id,
-            'title': title,
-            'description': data.get('description'),
-            'duration': duration,
-            'thumbnail': data.get('thumbnail'),
-            'timestamp': float_or_none(data.get('publishTime'), scale=1000),
-            'view_count': get_insight('view'),
-            'like_count': get_insight('like'),
-            'formats': formats,
-            'subtitles': subtitles,
-        }
-
-
-class EllenTubeIE(EllenTubeBaseIE):
-    _VALID_URL = r'''(?x)
-                        (?:
-                            ellentube:|
-                            https://api-prod\.ellentube\.com/ellenapi/api/item/
-                        )
-                        (?P<id>[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12})
-                    '''
-    _TESTS = [{
-        'url': 'https://api-prod.ellentube.com/ellenapi/api/item/0822171c-3829-43bf-b99f-d77358ae75e3',
-        'md5': '2fabc277131bddafdd120e0fc0f974c9',
-        'info_dict': {
-            'id': '0822171c-3829-43bf-b99f-d77358ae75e3',
-            'ext': 'mp4',
-            'title': 'Ellen Meets Las Vegas Survivors Jesus Campos and Stephen Schuck',
-            'description': 'md5:76e3355e2242a78ad9e3858e5616923f',
-            'thumbnail': r're:^https?://.+?',
-            'duration': 514,
-            'timestamp': 1508505120,
-            'upload_date': '20171020',
-            'view_count': int,
-            'like_count': int,
-        }
-    }, {
-        'url': 'ellentube:734a3353-f697-4e79-9ca9-bfc3002dc1e0',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        data = self._download_json(
-            'https://api-prod.ellentube.com/ellenapi/api/item/%s' % video_id,
-            video_id)
-        return self._extract_video(data, video_id)
-
-
-class EllenTubeVideoIE(EllenTubeBaseIE):
-    _VALID_URL = r'https?://(?:www\.)?ellentube\.com/video/(?P<id>.+?)\.html'
-    _TEST = {
-        'url': 'https://www.ellentube.com/video/ellen-meets-las-vegas-survivors-jesus-campos-and-stephen-schuck.html',
-        'only_matching': True,
-    }
-
-    def _real_extract(self, url):
-        display_id = self._match_id(url)
-        webpage = self._download_webpage(url, display_id)
-        video_id = self._extract_data_config(webpage, display_id)['id']
-        return self.url_result(
-            'ellentube:%s' % video_id, ie=EllenTubeIE.ie_key(),
-            video_id=video_id)
-
-
-class EllenTubePlaylistIE(EllenTubeBaseIE):
-    _VALID_URL = r'https?://(?:www\.)?ellentube\.com/(?:episode|studios)/(?P<id>.+?)\.html'
-    _TESTS = [{
-        'url': 'https://www.ellentube.com/episode/dax-shepard-jordan-fisher-haim.html',
-        'info_dict': {
-            'id': 'dax-shepard-jordan-fisher-haim',
-            'title': "Dax Shepard, 'DWTS' Team Jordan Fisher & Lindsay Arnold, HAIM",
-            'description': 'md5:bfc982194dabb3f4e325e43aa6b2e21c',
-        },
-        'playlist_count': 6,
-    }, {
-        'url': 'https://www.ellentube.com/studios/macey-goes-rving0.html',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        display_id = self._match_id(url)
-        webpage = self._download_webpage(url, display_id)
-        data = self._extract_data_config(webpage, display_id)['data']
-        feed = self._download_json(
-            'https://api-prod.ellentube.com/ellenapi/api/feed/?%s'
-            % data['filter'], display_id)
-        entries = [
-            self._extract_video(elem, elem['id'])
-            for elem in feed if elem.get('type') == 'VIDEO' and elem.get('id')]
-        return self.playlist_result(
-            entries, display_id, data.get('title'),
-            clean_html(data.get('description')))
diff --git a/yt_dlp/extractor/engadget.py b/yt_dlp/extractor/engadget.py
deleted file mode 100644 (file)
index e7c5d7b..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-from .common import InfoExtractor
-
-
-class EngadgetIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?engadget\.com/video/(?P<id>[^/?#]+)'
-
-    _TESTS = [{
-        # video with vidible ID
-        'url': 'https://www.engadget.com/video/57a28462134aa15a39f0421a/',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        return self.url_result('aol-video:%s' % video_id)
diff --git a/yt_dlp/extractor/escapist.py b/yt_dlp/extractor/escapist.py
deleted file mode 100644 (file)
index 85a1cbf..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    determine_ext,
-    clean_html,
-    int_or_none,
-    float_or_none,
-)
-
-
-def _decrypt_config(key, string):
-    a = ''
-    i = ''
-    r = ''
-
-    while len(a) < (len(string) / 2):
-        a += key
-
-    a = a[0:int(len(string) / 2)]
-
-    t = 0
-    while t < len(string):
-        i += chr(int(string[t] + string[t + 1], 16))
-        t += 2
-
-    icko = [s for s in i]
-
-    for t, c in enumerate(a):
-        r += chr(ord(c) ^ ord(icko[t]))
-
-    return r
-
-
-class EscapistIE(InfoExtractor):
-    _VALID_URL = r'https?://?(?:(?:www|v1)\.)?escapistmagazine\.com/videos/view/[^/]+/(?P<id>[0-9]+)'
-    _TESTS = [{
-        'url': 'http://www.escapistmagazine.com/videos/view/the-escapist-presents/6618-Breaking-Down-Baldurs-Gate',
-        'md5': 'ab3a706c681efca53f0a35f1415cf0d1',
-        'info_dict': {
-            'id': '6618',
-            'ext': 'mp4',
-            'description': "Baldur's Gate: Original, Modded or Enhanced Edition? I'll break down what you can expect from the new Baldur's Gate: Enhanced Edition.",
-            'title': "Breaking Down Baldur's Gate",
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'duration': 264,
-            'uploader': 'The Escapist',
-        }
-    }, {
-        'url': 'http://www.escapistmagazine.com/videos/view/zero-punctuation/10044-Evolve-One-vs-Multiplayer',
-        'md5': '9e8c437b0dbb0387d3bd3255ca77f6bf',
-        'info_dict': {
-            'id': '10044',
-            'ext': 'mp4',
-            'description': 'This week, Zero Punctuation reviews Evolve.',
-            'title': 'Evolve - One vs Multiplayer',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'duration': 304,
-            'uploader': 'The Escapist',
-        }
-    }, {
-        'url': 'http://escapistmagazine.com/videos/view/the-escapist-presents/6618',
-        'only_matching': True,
-    }, {
-        'url': 'https://v1.escapistmagazine.com/videos/view/the-escapist-presents/6618-Breaking-Down-Baldurs-Gate',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-
-        ims_video = self._parse_json(
-            self._search_regex(
-                r'imsVideo\.play\(({.+?})\);', webpage, 'imsVideo'),
-            video_id)
-        video_id = ims_video['videoID']
-        key = ims_video['hash']
-
-        config = self._download_webpage(
-            'http://www.escapistmagazine.com/videos/vidconfig.php',
-            video_id, 'Downloading video config', headers={
-                'Referer': url,
-            }, query={
-                'videoID': video_id,
-                'hash': key,
-            })
-
-        data = self._parse_json(_decrypt_config(key, config), video_id)
-
-        video_data = data['videoData']
-
-        title = clean_html(video_data['title'])
-
-        formats = [{
-            'url': video['src'],
-            'format_id': '%s-%sp' % (determine_ext(video['src']), video['res']),
-            'height': int_or_none(video.get('res')),
-        } for video in data['files']['videos']]
-
-        return {
-            'id': video_id,
-            'formats': formats,
-            'title': title,
-            'thumbnail': self._og_search_thumbnail(webpage) or data.get('poster'),
-            'description': self._og_search_description(webpage),
-            'duration': float_or_none(video_data.get('duration'), 1000),
-            'uploader': video_data.get('publisher'),
-            'series': video_data.get('show'),
-        }
diff --git a/yt_dlp/extractor/esri.py b/yt_dlp/extractor/esri.py
deleted file mode 100644 (file)
index 02e7efa..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..compat import compat_urlparse
-from ..utils import (
-    int_or_none,
-    parse_filesize,
-    unified_strdate,
-)
-
-
-class EsriVideoIE(InfoExtractor):
-    _VALID_URL = r'https?://video\.esri\.com/watch/(?P<id>[0-9]+)'
-    _TEST = {
-        'url': 'https://video.esri.com/watch/1124/arcgis-online-_dash_-developing-applications',
-        'md5': 'd4aaf1408b221f1b38227a9bbaeb95bc',
-        'info_dict': {
-            'id': '1124',
-            'ext': 'mp4',
-            'title': 'ArcGIS Online - Developing Applications',
-            'description': 'Jeremy Bartley demonstrates how to develop applications with ArcGIS Online.',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'duration': 185,
-            'upload_date': '20120419',
-        }
-    }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        webpage = self._download_webpage(url, video_id)
-
-        formats = []
-        for width, height, content in re.findall(
-                r'(?s)<li><strong>(\d+)x(\d+):</strong>(.+?)</li>', webpage):
-            for video_url, ext, filesize in re.findall(
-                    r'<a[^>]+href="([^"]+)">([^<]+)&nbsp;\(([^<]+)\)</a>', content):
-                formats.append({
-                    'url': compat_urlparse.urljoin(url, video_url),
-                    'ext': ext.lower(),
-                    'format_id': '%s-%s' % (ext.lower(), height),
-                    'width': int(width),
-                    'height': int(height),
-                    'filesize_approx': parse_filesize(filesize),
-                })
-
-        title = self._html_search_meta('title', webpage, 'title')
-        description = self._html_search_meta(
-            'description', webpage, 'description', fatal=False)
-
-        thumbnail = self._html_search_meta('thumbnail', webpage, 'thumbnail', fatal=False)
-        if thumbnail:
-            thumbnail = re.sub(r'_[st]\.jpg$', '_x.jpg', thumbnail)
-
-        duration = int_or_none(self._search_regex(
-            [r'var\s+videoSeconds\s*=\s*(\d+)', r"'duration'\s*:\s*(\d+)"],
-            webpage, 'duration', fatal=False))
-
-        upload_date = unified_strdate(self._html_search_meta(
-            'last-modified', webpage, 'upload date', fatal=False))
-
-        return {
-            'id': video_id,
-            'title': title,
-            'description': description,
-            'thumbnail': thumbnail,
-            'duration': duration,
-            'upload_date': upload_date,
-            'formats': formats
-        }
diff --git a/yt_dlp/extractor/expotv.py b/yt_dlp/extractor/expotv.py
deleted file mode 100644 (file)
index bda6e3c..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    int_or_none,
-    unified_strdate,
-)
-
-
-class ExpoTVIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?expotv\.com/videos/[^?#]*/(?P<id>[0-9]+)($|[?#])'
-    _TEST = {
-        'url': 'http://www.expotv.com/videos/reviews/3/40/NYX-Butter-lipstick/667916',
-        'md5': 'fe1d728c3a813ff78f595bc8b7a707a8',
-        'info_dict': {
-            'id': '667916',
-            'ext': 'mp4',
-            'title': 'NYX Butter Lipstick Little Susie',
-            'description': 'Goes on like butter, but looks better!',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'uploader': 'Stephanie S.',
-            'upload_date': '20150520',
-            'view_count': int,
-        }
-    }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        webpage = self._download_webpage(url, video_id)
-        player_key = self._search_regex(
-            r'<param name="playerKey" value="([^"]+)"', webpage, 'player key')
-        config = self._download_json(
-            'http://client.expotv.com/video/config/%s/%s' % (video_id, player_key),
-            video_id, 'Downloading video configuration')
-
-        formats = []
-        for fcfg in config['sources']:
-            media_url = fcfg.get('file')
-            if not media_url:
-                continue
-            if fcfg.get('type') == 'm3u8':
-                formats.extend(self._extract_m3u8_formats(
-                    media_url, video_id, 'mp4', entry_protocol='m3u8_native', m3u8_id='hls'))
-            else:
-                formats.append({
-                    'url': media_url,
-                    'height': int_or_none(fcfg.get('height')),
-                    'format_id': fcfg.get('label'),
-                    'ext': self._search_regex(
-                        r'filename=.*\.([a-z0-9_A-Z]+)&', media_url,
-                        'file extension', default=None) or fcfg.get('type'),
-                })
-
-        title = self._og_search_title(webpage)
-        description = self._og_search_description(webpage)
-        thumbnail = config.get('image')
-        view_count = int_or_none(self._search_regex(
-            r'<h5>Plays: ([0-9]+)</h5>', webpage, 'view counts'))
-        uploader = self._search_regex(
-            r'<div class="reviewer">\s*<img alt="([^"]+)"', webpage, 'uploader',
-            fatal=False)
-        upload_date = unified_strdate(self._search_regex(
-            r'<h5>Reviewed on ([0-9/.]+)</h5>', webpage, 'upload date',
-            fatal=False), day_first=False)
-
-        return {
-            'id': video_id,
-            'formats': formats,
-            'title': title,
-            'description': description,
-            'view_count': view_count,
-            'thumbnail': thumbnail,
-            'uploader': uploader,
-            'upload_date': upload_date,
-        }
diff --git a/yt_dlp/extractor/extremetube.py b/yt_dlp/extractor/extremetube.py
deleted file mode 100644 (file)
index 2c19698..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-from ..utils import str_to_int
-from .keezmovies import KeezMoviesIE
-
-
-class ExtremeTubeIE(KeezMoviesIE):  # XXX: Do not subclass from concrete IE
-    _VALID_URL = r'https?://(?:www\.)?extremetube\.com/(?:[^/]+/)?video/(?P<id>[^/#?&]+)'
-    _TESTS = [{
-        'url': 'http://www.extremetube.com/video/music-video-14-british-euro-brit-european-cumshots-swallow-652431',
-        'md5': '92feaafa4b58e82f261e5419f39c60cb',
-        'info_dict': {
-            'id': 'music-video-14-british-euro-brit-european-cumshots-swallow-652431',
-            'ext': 'mp4',
-            'title': 'Music Video 14 british euro brit european cumshots swallow',
-            'uploader': 'anonim',
-            'view_count': int,
-            'age_limit': 18,
-        }
-    }, {
-        'url': 'http://www.extremetube.com/gay/video/abcde-1234',
-        'only_matching': True,
-    }, {
-        'url': 'http://www.extremetube.com/video/latina-slut-fucked-by-fat-black-dick',
-        'only_matching': True,
-    }, {
-        'url': 'http://www.extremetube.com/video/652431',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        webpage, info = self._extract_info(url)
-
-        if not info['title']:
-            info['title'] = self._search_regex(
-                r'<h1[^>]+title="([^"]+)"[^>]*>', webpage, 'title')
-
-        uploader = self._html_search_regex(
-            r'Uploaded by:\s*</[^>]+>\s*<a[^>]+>(.+?)</a>',
-            webpage, 'uploader', fatal=False)
-        view_count = str_to_int(self._search_regex(
-            r'Views:\s*</[^>]+>\s*<[^>]+>([\d,\.]+)</',
-            webpage, 'view count', fatal=False))
-
-        info.update({
-            'uploader': uploader,
-            'view_count': view_count,
-        })
-
-        return info
diff --git a/yt_dlp/extractor/fourzerostudio.py b/yt_dlp/extractor/fourzerostudio.py
deleted file mode 100644 (file)
index c388a3a..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-from .common import InfoExtractor
-from ..utils import traverse_obj, unified_timestamp
-
-
-class FourZeroStudioArchiveIE(InfoExtractor):
-    _VALID_URL = r'https?://0000\.studio/(?P<uploader_id>[^/]+)/broadcasts/(?P<id>[^/]+)/archive'
-    IE_NAME = '0000studio:archive'
-    _TESTS = [{
-        'url': 'https://0000.studio/mumeijiten/broadcasts/1290f433-fce0-4909-a24a-5f7df09665dc/archive',
-        'info_dict': {
-            'id': '1290f433-fce0-4909-a24a-5f7df09665dc',
-            'title': 'noteで『canape』様へのファンレターを執筆します。(数秘術その2)',
-            'timestamp': 1653802534,
-            'release_timestamp': 1653796604,
-            'thumbnails': 'count:1',
-            'comments': 'count:7',
-            'uploader': '『中崎雄心』の執務室。',
-            'uploader_id': 'mumeijiten',
-        }
-    }]
-
-    def _real_extract(self, url):
-        video_id, uploader_id = self._match_valid_url(url).group('id', 'uploader_id')
-        webpage = self._download_webpage(url, video_id)
-        nuxt_data = self._search_nuxt_data(webpage, video_id, traverse=None)
-
-        pcb = traverse_obj(nuxt_data, ('ssrRefs', lambda _, v: v['__typename'] == 'PublicCreatorBroadcast'), get_all=False)
-        uploader_internal_id = traverse_obj(nuxt_data, (
-            'ssrRefs', lambda _, v: v['__typename'] == 'PublicUser', 'id'), get_all=False)
-
-        formats, subs = self._extract_m3u8_formats_and_subtitles(pcb['archiveUrl'], video_id, ext='mp4')
-
-        return {
-            'id': video_id,
-            'title': pcb.get('title'),
-            'age_limit': 18 if pcb.get('isAdult') else None,
-            'timestamp': unified_timestamp(pcb.get('finishTime')),
-            'release_timestamp': unified_timestamp(pcb.get('createdAt')),
-            'thumbnails': [{
-                'url': pcb['thumbnailUrl'],
-                'ext': 'png',
-            }] if pcb.get('thumbnailUrl') else None,
-            'formats': formats,
-            'subtitles': subs,
-            'comments': [{
-                'author': c.get('username'),
-                'author_id': c.get('postedUserId'),
-                'author_thumbnail': c.get('userThumbnailUrl'),
-                'id': c.get('id'),
-                'text': c.get('body'),
-                'timestamp': unified_timestamp(c.get('createdAt')),
-                'like_count': c.get('likeCount'),
-                'is_favorited': c.get('isLikedByOwner'),
-                'author_is_uploader': c.get('postedUserId') == uploader_internal_id,
-            } for c in traverse_obj(nuxt_data, (
-                'ssrRefs', ..., lambda _, v: v['__typename'] == 'PublicCreatorBroadcastComment')) or []],
-            'uploader_id': uploader_id,
-            'uploader': traverse_obj(nuxt_data, (
-                'ssrRefs', lambda _, v: v['__typename'] == 'PublicUser', 'username'), get_all=False),
-        }
-
-
-class FourZeroStudioClipIE(InfoExtractor):
-    _VALID_URL = r'https?://0000\.studio/(?P<uploader_id>[^/]+)/archive-clip/(?P<id>[^/]+)'
-    IE_NAME = '0000studio:clip'
-    _TESTS = [{
-        'url': 'https://0000.studio/soeji/archive-clip/e46b0278-24cd-40a8-92e1-b8fc2b21f34f',
-        'info_dict': {
-            'id': 'e46b0278-24cd-40a8-92e1-b8fc2b21f34f',
-            'title': 'わたベーさんからイラスト差し入れいただきました。ありがとうございました!',
-            'timestamp': 1652109105,
-            'like_count': 1,
-            'uploader': 'ソエジマケイタ',
-            'uploader_id': 'soeji',
-        }
-    }]
-
-    def _real_extract(self, url):
-        video_id, uploader_id = self._match_valid_url(url).group('id', 'uploader_id')
-        webpage = self._download_webpage(url, video_id)
-        nuxt_data = self._search_nuxt_data(webpage, video_id, traverse=None)
-
-        clip_info = traverse_obj(nuxt_data, ('ssrRefs', lambda _, v: v['__typename'] == 'PublicCreatorArchivedClip'), get_all=False)
-
-        info = next((
-            m for m in self._parse_html5_media_entries(url, webpage, video_id)
-            if 'mp4' in traverse_obj(m, ('formats', ..., 'ext'))
-        ), None)
-        if not info:
-            self.report_warning('Failed to find a desired media element. Falling back to using NUXT data.')
-            info = {
-                'formats': [{
-                    'ext': 'mp4',
-                    'url': url,
-                } for url in clip_info.get('mediaFiles') or [] if url],
-            }
-        return {
-            **info,
-            'id': video_id,
-            'title': clip_info.get('clipComment'),
-            'timestamp': unified_timestamp(clip_info.get('createdAt')),
-            'like_count': clip_info.get('likeCount'),
-            'uploader_id': uploader_id,
-            'uploader': traverse_obj(nuxt_data, (
-                'ssrRefs', lambda _, v: v['__typename'] == 'PublicUser', 'username'), get_all=False),
-        }
diff --git a/yt_dlp/extractor/foxgay.py b/yt_dlp/extractor/foxgay.py
deleted file mode 100644 (file)
index f4f29c6..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-import itertools
-
-from .common import InfoExtractor
-from ..utils import (
-    get_element_by_id,
-    int_or_none,
-    remove_end,
-)
-
-
-class FoxgayIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?foxgay\.com/videos/(?:\S+-)?(?P<id>\d+)\.shtml'
-    _TEST = {
-        'url': 'http://foxgay.com/videos/fuck-turkish-style-2582.shtml',
-        'md5': '344558ccfea74d33b7adbce22e577f54',
-        'info_dict': {
-            'id': '2582',
-            'ext': 'mp4',
-            'title': 'Fuck Turkish-style',
-            'description': 'md5:6ae2d9486921891efe89231ace13ffdf',
-            'age_limit': 18,
-            'thumbnail': r're:https?://.*\.jpg$',
-        },
-    }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-
-        title = remove_end(self._html_extract_title(webpage), ' - Foxgay.com')
-        description = get_element_by_id('inf_tit', webpage)
-
-        # The default user-agent with foxgay cookies leads to pages without videos
-        self.cookiejar.clear('.foxgay.com')
-        # Find the URL for the iFrame which contains the actual video.
-        iframe_url = self._html_search_regex(
-            r'<iframe[^>]+src=([\'"])(?P<url>[^\'"]+)\1', webpage,
-            'video frame', group='url')
-        iframe = self._download_webpage(
-            iframe_url, video_id, headers={'User-Agent': 'curl/7.50.1'},
-            note='Downloading video frame')
-        video_data = self._parse_json(self._search_regex(
-            r'video_data\s*=\s*([^;]+);', iframe, 'video data'), video_id)
-
-        formats = [{
-            'url': source,
-            'height': int_or_none(resolution),
-        } for source, resolution in zip(
-            video_data['sources'], video_data.get('resolutions', itertools.repeat(None)))]
-
-        return {
-            'id': video_id,
-            'title': title,
-            'formats': formats,
-            'description': description,
-            'thumbnail': video_data.get('act_vid', {}).get('thumb'),
-            'age_limit': 18,
-        }
diff --git a/yt_dlp/extractor/fusion.py b/yt_dlp/extractor/fusion.py
deleted file mode 100644 (file)
index 689422f..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    determine_ext,
-    int_or_none,
-    mimetype2ext,
-    parse_iso8601,
-)
-
-
-class FusionIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?fusion\.(?:net|tv)/(?:video/|show/.+?\bvideo=)(?P<id>\d+)'
-    _TESTS = [{
-        'url': 'http://fusion.tv/video/201781/u-s-and-panamanian-forces-work-together-to-stop-a-vessel-smuggling-drugs/',
-        'info_dict': {
-            'id': '3145868',
-            'ext': 'mp4',
-            'title': 'U.S. and Panamanian forces work together to stop a vessel smuggling drugs',
-            'description': 'md5:0cc84a9943c064c0f46b128b41b1b0d7',
-            'duration': 140.0,
-            'timestamp': 1442589635,
-            'uploader': 'UNIVISON',
-            'upload_date': '20150918',
-        },
-        'params': {
-            'skip_download': True,
-        },
-        'add_ie': ['Anvato'],
-    }, {
-        'url': 'http://fusion.tv/video/201781',
-        'only_matching': True,
-    }, {
-        'url': 'https://fusion.tv/show/food-exposed-with-nelufar-hedayat/?ancla=full-episodes&video=588644',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        video = self._download_json(
-            'https://platform.fusion.net/wp-json/fusiondotnet/v1/video/' + video_id, video_id)
-
-        info = {
-            'id': video_id,
-            'title': video['title'],
-            'description': video.get('excerpt'),
-            'timestamp': parse_iso8601(video.get('published')),
-            'series': video.get('show'),
-        }
-
-        formats = []
-        src = video.get('src') or {}
-        for f_id, f in src.items():
-            for q_id, q in f.items():
-                q_url = q.get('url')
-                if not q_url:
-                    continue
-                ext = determine_ext(q_url, mimetype2ext(q.get('type')))
-                if ext == 'smil':
-                    formats.extend(self._extract_smil_formats(q_url, video_id, fatal=False))
-                elif f_id == 'm3u8-variant' or (ext == 'm3u8' and q_id == 'Variant'):
-                    formats.extend(self._extract_m3u8_formats(
-                        q_url, video_id, 'mp4', 'm3u8_native', m3u8_id='hls', fatal=False))
-                else:
-                    formats.append({
-                        'format_id': '-'.join([f_id, q_id]),
-                        'url': q_url,
-                        'width': int_or_none(q.get('width')),
-                        'height': int_or_none(q.get('height')),
-                        'tbr': int_or_none(self._search_regex(r'_(\d+)\.m(?:p4|3u8)', q_url, 'bitrate')),
-                        'ext': 'mp4' if ext == 'm3u8' else ext,
-                        'protocol': 'm3u8_native' if ext == 'm3u8' else 'https',
-                    })
-        if formats:
-            info['formats'] = formats
-        else:
-            info.update({
-                '_type': 'url',
-                'url': 'anvato:uni:' + video['video_ids']['anvato'],
-                'ie_key': 'Anvato',
-            })
-
-        return info
index 1503e5146edebbfe045db52009c54320c9dbdfe4..606b4f5d1e3b3cab95f3bd77418f39e8bfb9f46a 100644 (file)
@@ -374,46 +374,6 @@ class GenericIE(InfoExtractor):
             },
             'skip': 'There is a limit of 200 free downloads / month for the test song',
         },
             },
             'skip': 'There is a limit of 200 free downloads / month for the test song',
         },
-        # ooyala video
-        {
-            'url': 'http://www.rollingstone.com/music/videos/norwegian-dj-cashmere-cat-goes-spartan-on-with-me-premiere-20131219',
-            'md5': '166dd577b433b4d4ebfee10b0824d8ff',
-            'info_dict': {
-                'id': 'BwY2RxaTrTkslxOfcan0UCf0YqyvWysJ',
-                'ext': 'mp4',
-                'title': '2cc213299525360.mov',  # that's what we get
-                'duration': 238.231,
-            },
-            'add_ie': ['Ooyala'],
-        },
-        {
-            # ooyala video embedded with http://player.ooyala.com/iframe.js
-            'url': 'http://www.macrumors.com/2015/07/24/steve-jobs-the-man-in-the-machine-first-trailer/',
-            'info_dict': {
-                'id': 'p0MGJndjoG5SOKqO_hZJuZFPB-Tr5VgB',
-                'ext': 'mp4',
-                'title': '"Steve Jobs: Man in the Machine" trailer',
-                'description': 'The first trailer for the Alex Gibney documentary "Steve Jobs: Man in the Machine."',
-                'duration': 135.427,
-            },
-            'params': {
-                'skip_download': True,
-            },
-            'skip': 'movie expired',
-        },
-        # ooyala video embedded with http://player.ooyala.com/static/v4/production/latest/core.min.js
-        {
-            'url': 'http://wnep.com/2017/07/22/steampunk-fest-comes-to-honesdale/',
-            'info_dict': {
-                'id': 'lwYWYxYzE6V5uJMjNGyKtwwiw9ZJD7t2',
-                'ext': 'mp4',
-                'title': 'Steampunk Fest Comes to Honesdale',
-                'duration': 43.276,
-            },
-            'params': {
-                'skip_download': True,
-            }
-        },
         # embed.ly video
         {
             'url': 'http://www.tested.com/science/weird/460206-tested-grinding-coffee-2000-frames-second/',
         # embed.ly video
         {
             'url': 'http://www.tested.com/science/weird/460206-tested-grinding-coffee-2000-frames-second/',
@@ -506,7 +466,8 @@ class GenericIE(InfoExtractor):
                 'title': 'Ужастики, русский трейлер (2015)',
                 'thumbnail': r're:^https?://.*\.jpg$',
                 'duration': 153,
                 'title': 'Ужастики, русский трейлер (2015)',
                 'thumbnail': r're:^https?://.*\.jpg$',
                 'duration': 153,
-            }
+            },
+            'skip': 'Site dead',
         },
         # XHamster embed
         {
         },
         # XHamster embed
         {
@@ -778,14 +739,16 @@ class GenericIE(InfoExtractor):
             'playlist_mincount': 1,
             'add_ie': ['Youtube'],
         },
             'playlist_mincount': 1,
             'add_ie': ['Youtube'],
         },
-        # Cinchcast embed
+        # Libsyn embed
         {
             'url': 'http://undergroundwellness.com/podcasts/306-5-steps-to-permanent-gut-healing/',
             'info_dict': {
         {
             'url': 'http://undergroundwellness.com/podcasts/306-5-steps-to-permanent-gut-healing/',
             'info_dict': {
-                'id': '7141703',
+                'id': '3793998',
                 'ext': 'mp3',
                 'upload_date': '20141126',
                 'ext': 'mp3',
                 'upload_date': '20141126',
-                'title': 'Jack Tips: 5 Steps to Permanent Gut Healing',
+                'title': 'Underground Wellness Radio - Jack Tips: 5 Steps to Permanent Gut Healing',
+                'thumbnail': 'https://assets.libsyn.com/secure/item/3793998/?height=90&width=90',
+                'duration': 3989.0,
             }
         },
         # Cinerama player
             }
         },
         # Cinerama player
@@ -1567,16 +1530,6 @@ class GenericIE(InfoExtractor):
                 'title': 'Стас Намин: «Мы нарушили девственность Кремля»',
             },
         },
                 'title': 'Стас Намин: «Мы нарушили девственность Кремля»',
             },
         },
-        {
-            # vzaar embed
-            'url': 'http://help.vzaar.com/article/165-embedding-video',
-            'md5': '7e3919d9d2620b89e3e00bec7fe8c9d4',
-            'info_dict': {
-                'id': '8707641',
-                'ext': 'mp4',
-                'title': 'Building A Business Online: Principal Chairs Q & A',
-            },
-        },
         {
             # multiple HTML5 videos on one page
             'url': 'https://www.paragon-software.com/home/rk-free/keyscenarios.html',
         {
             # multiple HTML5 videos on one page
             'url': 'https://www.paragon-software.com/home/rk-free/keyscenarios.html',
diff --git a/yt_dlp/extractor/gfycat.py b/yt_dlp/extractor/gfycat.py
deleted file mode 100644 (file)
index edc2e56..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    int_or_none,
-    float_or_none,
-    qualities,
-    ExtractorError,
-)
-
-
-class GfycatIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:(?:www|giant|thumbs)\.)?gfycat\.com/(?i:ru/|ifr/|gifs/detail/)?(?P<id>[^-/?#\."\']+)'
-    _EMBED_REGEX = [rf'<(?:iframe|source)[^>]+\bsrc=["\'](?P<url>{_VALID_URL})']
-    _TESTS = [{
-        'url': 'http://gfycat.com/DeadlyDecisiveGermanpinscher',
-        'info_dict': {
-            'id': 'DeadlyDecisiveGermanpinscher',
-            'ext': 'mp4',
-            'title': 'Ghost in the Shell',
-            'timestamp': 1410656006,
-            'upload_date': '20140914',
-            'uploader': 'anonymous',
-            'duration': 10.4,
-            'view_count': int,
-            'like_count': int,
-            'categories': list,
-            'age_limit': 0,
-            'uploader_id': 'anonymous',
-            'description': '',
-        }
-    }, {
-        'url': 'http://gfycat.com/ifr/JauntyTimelyAmazontreeboa',
-        'info_dict': {
-            'id': 'JauntyTimelyAmazontreeboa',
-            'ext': 'mp4',
-            'title': 'JauntyTimelyAmazontreeboa',
-            'timestamp': 1411720126,
-            'upload_date': '20140926',
-            'uploader': 'anonymous',
-            'duration': 3.52,
-            'view_count': int,
-            'like_count': int,
-            'categories': list,
-            'age_limit': 0,
-            'uploader_id': 'anonymous',
-            'description': '',
-        }
-    }, {
-        'url': 'https://gfycat.com/alienatedsolidgreathornedowl',
-        'info_dict': {
-            'id': 'alienatedsolidgreathornedowl',
-            'ext': 'mp4',
-            'upload_date': '20211226',
-            'uploader_id': 'reactions',
-            'timestamp': 1640536930,
-            'like_count': int,
-            'description': '',
-            'title': 'Ingrid Michaelson, Zooey Deschanel - Merry Christmas Happy New Year',
-            'categories': list,
-            'age_limit': 0,
-            'duration': 2.9583333333333335,
-            'uploader': 'Reaction GIFs',
-            'view_count': int,
-        }
-    }, {
-        'url': 'https://gfycat.com/ru/RemarkableDrearyAmurstarfish',
-        'only_matching': True
-    }, {
-        'url': 'https://gfycat.com/gifs/detail/UnconsciousLankyIvorygull',
-        'only_matching': True
-    }, {
-        'url': 'https://gfycat.com/acceptablehappygoluckyharborporpoise-baseball',
-        'only_matching': True
-    }, {
-        'url': 'https://thumbs.gfycat.com/acceptablehappygoluckyharborporpoise-size_restricted.gif',
-        'only_matching': True
-    }, {
-        'url': 'https://giant.gfycat.com/acceptablehappygoluckyharborporpoise.mp4',
-        'only_matching': True
-    }, {
-        'url': 'http://gfycat.com/IFR/JauntyTimelyAmazontreeboa',
-        'only_matching': True
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        gfy = self._download_json(
-            'https://api.gfycat.com/v1/gfycats/%s' % video_id,
-            video_id, 'Downloading video info')
-        if 'error' in gfy:
-            raise ExtractorError('Gfycat said: ' + gfy['error'], expected=True)
-        gfy = gfy['gfyItem']
-
-        title = gfy.get('title') or gfy['gfyName']
-        description = gfy.get('description')
-        timestamp = int_or_none(gfy.get('createDate'))
-        uploader = gfy.get('userName') or gfy.get('username')
-        view_count = int_or_none(gfy.get('views'))
-        like_count = int_or_none(gfy.get('likes'))
-        dislike_count = int_or_none(gfy.get('dislikes'))
-        age_limit = 18 if gfy.get('nsfw') == '1' else 0
-
-        width = int_or_none(gfy.get('width'))
-        height = int_or_none(gfy.get('height'))
-        fps = int_or_none(gfy.get('frameRate'))
-        num_frames = int_or_none(gfy.get('numFrames'))
-
-        duration = float_or_none(num_frames, fps) if num_frames and fps else None
-
-        categories = gfy.get('tags') or gfy.get('extraLemmas') or []
-
-        FORMATS = ('gif', 'webm', 'mp4')
-        quality = qualities(FORMATS)
-
-        formats = []
-        for format_id in FORMATS:
-            video_url = gfy.get('%sUrl' % format_id)
-            if not video_url:
-                continue
-            filesize = int_or_none(gfy.get('%sSize' % format_id))
-            formats.append({
-                'url': video_url,
-                'format_id': format_id,
-                'width': width,
-                'height': height,
-                'fps': fps,
-                'filesize': filesize,
-                'quality': quality(format_id),
-            })
-
-        return {
-            'id': video_id,
-            'title': title,
-            'description': description,
-            'timestamp': timestamp,
-            'uploader': gfy.get('userDisplayName') or uploader,
-            'uploader_id': uploader,
-            'duration': duration,
-            'view_count': view_count,
-            'like_count': like_count,
-            'dislike_count': dislike_count,
-            'categories': categories,
-            'age_limit': age_limit,
-            'formats': formats,
-        }
index 362d3ff831a15283240ee1ffdc8e8182d8af4c9d..c1cbda35f0f1a18774ed8687b809afd41f6ceb61 100644 (file)
@@ -31,7 +31,6 @@ class GrouponIE(InfoExtractor):
     }
 
     _PROVIDERS = {
     }
 
     _PROVIDERS = {
-        'ooyala': ('ooyala:%s', 'Ooyala'),
         'youtube': ('%s', 'Youtube'),
     }
 
         'youtube': ('%s', 'Youtube'),
     }
 
diff --git a/yt_dlp/extractor/helsinki.py b/yt_dlp/extractor/helsinki.py
deleted file mode 100644 (file)
index e518cae..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-from .common import InfoExtractor
-from ..utils import js_to_json
-
-
-class HelsinkiIE(InfoExtractor):
-    IE_DESC = 'helsinki.fi'
-    _VALID_URL = r'https?://video\.helsinki\.fi/Arkisto/flash\.php\?id=(?P<id>\d+)'
-    _TEST = {
-        'url': 'http://video.helsinki.fi/Arkisto/flash.php?id=20258',
-        'info_dict': {
-            'id': '20258',
-            'ext': 'mp4',
-            'title': 'Tietotekniikkafoorumi-iltapäivä',
-            'description': 'md5:f5c904224d43c133225130fe156a5ee0',
-        },
-        'params': {
-            'skip_download': True,  # RTMP
-        }
-    }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-
-        params = self._parse_json(self._html_search_regex(
-            r'(?s)jwplayer\("player"\).setup\((\{.*?\})\);',
-            webpage, 'player code'), video_id, transform_source=js_to_json)
-        formats = [{
-            'url': s['file'],
-            'ext': 'mp4',
-        } for s in params['sources']]
-
-        return {
-            'id': video_id,
-            'title': self._og_search_title(webpage).replace('Video: ', ''),
-            'description': self._og_search_description(webpage),
-            'formats': formats,
-        }
diff --git a/yt_dlp/extractor/hitbox.py b/yt_dlp/extractor/hitbox.py
deleted file mode 100644 (file)
index f0c6898..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..compat import compat_str
-from ..utils import (
-    clean_html,
-    determine_ext,
-    float_or_none,
-    int_or_none,
-    parse_iso8601,
-)
-
-
-class HitboxIE(InfoExtractor):
-    IE_NAME = 'hitbox'
-    _VALID_URL = r'https?://(?:www\.)?(?:hitbox|smashcast)\.tv/(?:[^/]+/)*videos?/(?P<id>[0-9]+)'
-    _TESTS = [{
-        'url': 'http://www.hitbox.tv/video/203213',
-        'info_dict': {
-            'id': '203213',
-            'title': 'hitbox @ gamescom, Sub Button Hype extended, Giveaway - hitbox News Update with Oxy',
-            'alt_title': 'hitboxlive - Aug 9th #6',
-            'description': '',
-            'ext': 'mp4',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'duration': 215.1666,
-            'resolution': 'HD 720p',
-            'uploader': 'hitboxlive',
-            'view_count': int,
-            'timestamp': 1407576133,
-            'upload_date': '20140809',
-            'categories': ['Live Show'],
-        },
-        'params': {
-            # m3u8 download
-            'skip_download': True,
-        },
-    }, {
-        'url': 'https://www.smashcast.tv/hitboxlive/videos/203213',
-        'only_matching': True,
-    }]
-
-    def _extract_metadata(self, url, video_id):
-        thumb_base = 'https://edge.sf.hitbox.tv'
-        metadata = self._download_json(
-            '%s/%s' % (url, video_id), video_id, 'Downloading metadata JSON')
-
-        date = 'media_live_since'
-        media_type = 'livestream'
-        if metadata.get('media_type') == 'video':
-            media_type = 'video'
-            date = 'media_date_added'
-
-        video_meta = metadata.get(media_type, [])[0]
-        title = video_meta.get('media_status')
-        alt_title = video_meta.get('media_title')
-        description = clean_html(
-            video_meta.get('media_description')
-            or video_meta.get('media_description_md'))
-        duration = float_or_none(video_meta.get('media_duration'))
-        uploader = video_meta.get('media_user_name')
-        views = int_or_none(video_meta.get('media_views'))
-        timestamp = parse_iso8601(video_meta.get(date), ' ')
-        categories = [video_meta.get('category_name')]
-        thumbs = [{
-            'url': thumb_base + video_meta.get('media_thumbnail'),
-            'width': 320,
-            'height': 180
-        }, {
-            'url': thumb_base + video_meta.get('media_thumbnail_large'),
-            'width': 768,
-            'height': 432
-        }]
-
-        return {
-            'id': video_id,
-            'title': title,
-            'alt_title': alt_title,
-            'description': description,
-            'ext': 'mp4',
-            'thumbnails': thumbs,
-            'duration': duration,
-            'uploader': uploader,
-            'view_count': views,
-            'timestamp': timestamp,
-            'categories': categories,
-        }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        player_config = self._download_json(
-            'https://www.smashcast.tv/api/player/config/video/%s' % video_id,
-            video_id, 'Downloading video JSON')
-
-        formats = []
-        for video in player_config['clip']['bitrates']:
-            label = video.get('label')
-            if label == 'Auto':
-                continue
-            video_url = video.get('url')
-            if not video_url:
-                continue
-            bitrate = int_or_none(video.get('bitrate'))
-            if determine_ext(video_url) == 'm3u8':
-                if not video_url.startswith('http'):
-                    continue
-                formats.append({
-                    'url': video_url,
-                    'ext': 'mp4',
-                    'tbr': bitrate,
-                    'format_note': label,
-                    'protocol': 'm3u8_native',
-                })
-            else:
-                formats.append({
-                    'url': video_url,
-                    'tbr': bitrate,
-                    'format_note': label,
-                })
-
-        metadata = self._extract_metadata(
-            'https://www.smashcast.tv/api/media/video', video_id)
-        metadata['formats'] = formats
-
-        return metadata
-
-
-class HitboxLiveIE(HitboxIE):  # XXX: Do not subclass from concrete IE
-    IE_NAME = 'hitbox:live'
-    _VALID_URL = r'https?://(?:www\.)?(?:hitbox|smashcast)\.tv/(?P<id>[^/?#&]+)'
-    _TESTS = [{
-        'url': 'http://www.hitbox.tv/dimak',
-        'info_dict': {
-            'id': 'dimak',
-            'ext': 'mp4',
-            'description': 'md5:c9f80fa4410bc588d7faa40003fc7d0e',
-            'timestamp': int,
-            'upload_date': compat_str,
-            'title': compat_str,
-            'uploader': 'Dimak',
-        },
-        'params': {
-            # live
-            'skip_download': True,
-        },
-    }, {
-        'url': 'https://www.smashcast.tv/dimak',
-        'only_matching': True,
-    }]
-
-    @classmethod
-    def suitable(cls, url):
-        return False if HitboxIE.suitable(url) else super(HitboxLiveIE, cls).suitable(url)
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        player_config = self._download_json(
-            'https://www.smashcast.tv/api/player/config/live/%s' % video_id,
-            video_id)
-
-        formats = []
-        cdns = player_config.get('cdns')
-        servers = []
-        for cdn in cdns:
-            # Subscribe URLs are not playable
-            if cdn.get('rtmpSubscribe') is True:
-                continue
-            base_url = cdn.get('netConnectionUrl')
-            host = re.search(r'.+\.([^\.]+\.[^\./]+)/.+', base_url).group(1)
-            if base_url not in servers:
-                servers.append(base_url)
-                for stream in cdn.get('bitrates'):
-                    label = stream.get('label')
-                    if label == 'Auto':
-                        continue
-                    stream_url = stream.get('url')
-                    if not stream_url:
-                        continue
-                    bitrate = int_or_none(stream.get('bitrate'))
-                    if stream.get('provider') == 'hls' or determine_ext(stream_url) == 'm3u8':
-                        if not stream_url.startswith('http'):
-                            continue
-                        formats.append({
-                            'url': stream_url,
-                            'ext': 'mp4',
-                            'tbr': bitrate,
-                            'format_note': label,
-                            'rtmp_live': True,
-                        })
-                    else:
-                        formats.append({
-                            'url': '%s/%s' % (base_url, stream_url),
-                            'ext': 'mp4',
-                            'tbr': bitrate,
-                            'rtmp_live': True,
-                            'format_note': host,
-                            'page_url': url,
-                            'player_url': 'http://www.hitbox.tv/static/player/flowplayer/flowplayer.commercial-3.2.16.swf',
-                        })
-
-        metadata = self._extract_metadata(
-            'https://www.smashcast.tv/api/media/live', video_id)
-        metadata['formats'] = formats
-        metadata['is_live'] = True
-        metadata['title'] = metadata.get('title')
-
-        return metadata
diff --git a/yt_dlp/extractor/howcast.py b/yt_dlp/extractor/howcast.py
deleted file mode 100644 (file)
index 59cf80f..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-from .common import InfoExtractor
-from ..utils import parse_iso8601
-
-
-class HowcastIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?howcast\.com/videos/(?P<id>\d+)'
-    _TEST = {
-        'url': 'http://www.howcast.com/videos/390161-How-to-Tie-a-Square-Knot-Properly',
-        'md5': '7d45932269a288149483144f01b99789',
-        'info_dict': {
-            'id': '390161',
-            'ext': 'mp4',
-            'title': 'How to Tie a Square Knot Properly',
-            'description': 'md5:dbe792e5f6f1489027027bf2eba188a3',
-            'timestamp': 1276081287,
-            'upload_date': '20100609',
-            'duration': 56.823,
-        },
-        'params': {
-            'skip_download': True,
-        },
-        'add_ie': ['Ooyala'],
-    }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        webpage = self._download_webpage(url, video_id)
-
-        embed_code = self._search_regex(
-            r'<iframe[^>]+src="[^"]+\bembed_code=([^\b]+)\b',
-            webpage, 'ooyala embed code')
-
-        return {
-            '_type': 'url_transparent',
-            'ie_key': 'Ooyala',
-            'url': 'ooyala:%s' % embed_code,
-            'id': video_id,
-            'timestamp': parse_iso8601(self._html_search_meta(
-                'article:published_time', webpage, 'timestamp')),
-        }
diff --git a/yt_dlp/extractor/howstuffworks.py b/yt_dlp/extractor/howstuffworks.py
deleted file mode 100644 (file)
index 238fc0b..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    find_xpath_attr,
-    int_or_none,
-    js_to_json,
-    unescapeHTML,
-    determine_ext,
-)
-
-
-class HowStuffWorksIE(InfoExtractor):
-    _VALID_URL = r'https?://[\da-z-]+\.(?:howstuffworks|stuff(?:(?:youshould|theydontwantyouto)know|toblowyourmind|momnevertoldyou)|(?:brain|car)stuffshow|fwthinking|geniusstuff)\.com/(?:[^/]+/)*(?:\d+-)?(?P<id>.+?)-video\.htm'
-    _TESTS = [
-        {
-            'url': 'http://www.stufftoblowyourmind.com/videos/optical-illusions-video.htm',
-            'md5': '76646a5acc0c92bf7cd66751ca5db94d',
-            'info_dict': {
-                'id': '855410',
-                'ext': 'mp4',
-                'title': 'Your Trickster Brain: Optical Illusions -- Science on the Web',
-                'description': 'md5:e374ff9561f6833ad076a8cc0a5ab2fb',
-            },
-        },
-        {
-            'url': 'http://shows.howstuffworks.com/more-shows/why-does-balloon-stick-to-hair-video.htm',
-            'only_matching': True,
-        }
-    ]
-
-    def _real_extract(self, url):
-        display_id = self._match_id(url)
-        webpage = self._download_webpage(url, display_id)
-        clip_js = self._search_regex(
-            r'(?s)var clip = ({.*?});', webpage, 'clip info')
-        clip_info = self._parse_json(
-            clip_js, display_id, transform_source=js_to_json)
-
-        video_id = clip_info['content_id']
-        formats = []
-        m3u8_url = clip_info.get('m3u8')
-        if m3u8_url and determine_ext(m3u8_url) == 'm3u8':
-            formats.extend(self._extract_m3u8_formats(m3u8_url, video_id, 'mp4', format_id='hls', fatal=True))
-        flv_url = clip_info.get('flv_url')
-        if flv_url:
-            formats.append({
-                'url': flv_url,
-                'format_id': 'flv',
-            })
-        for video in clip_info.get('mp4', []):
-            formats.append({
-                'url': video['src'],
-                'format_id': 'mp4-%s' % video['bitrate'],
-                'vbr': int_or_none(video['bitrate'].rstrip('k')),
-            })
-
-        if not formats:
-            smil = self._download_xml(
-                'http://services.media.howstuffworks.com/videos/%s/smil-service.smil' % video_id,
-                video_id, 'Downloading video SMIL')
-
-            http_base = find_xpath_attr(
-                smil,
-                './{0}head/{0}meta'.format('{http://www.w3.org/2001/SMIL20/Language}'),
-                'name',
-                'httpBase').get('content')
-
-            URL_SUFFIX = '?v=2.11.3&fp=LNX 11,2,202,356&r=A&g=A'
-
-            for video in smil.findall(
-                    './{0}body/{0}switch/{0}video'.format('{http://www.w3.org/2001/SMIL20/Language}')):
-                vbr = int_or_none(video.attrib['system-bitrate'], scale=1000)
-                formats.append({
-                    'url': '%s/%s%s' % (http_base, video.attrib['src'], URL_SUFFIX),
-                    'format_id': '%dk' % vbr,
-                    'vbr': vbr,
-                })
-
-        return {
-            'id': '%s' % video_id,
-            'display_id': display_id,
-            'title': unescapeHTML(clip_info['clip_title']),
-            'description': unescapeHTML(clip_info.get('caption')),
-            'thumbnail': clip_info.get('video_still_url'),
-            'duration': int_or_none(clip_info.get('duration')),
-            'formats': formats,
-        }
diff --git a/yt_dlp/extractor/keezmovies.py b/yt_dlp/extractor/keezmovies.py
deleted file mode 100644 (file)
index b50da42..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..aes import aes_decrypt_text
-from ..compat import compat_urllib_parse_unquote
-from ..utils import (
-    determine_ext,
-    format_field,
-    int_or_none,
-    str_to_int,
-    strip_or_none,
-    url_or_none,
-)
-
-
-class KeezMoviesIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?keezmovies\.com/video/(?:(?P<display_id>[^/]+)-)?(?P<id>\d+)'
-    _TESTS = [{
-        'url': 'https://www.keezmovies.com/video/arab-wife-want-it-so-bad-i-see-she-thirsty-and-has-tiny-money-18070681',
-        'md5': '2ac69cdb882055f71d82db4311732a1a',
-        'info_dict': {
-            'id': '18070681',
-            'display_id': 'arab-wife-want-it-so-bad-i-see-she-thirsty-and-has-tiny-money',
-            'ext': 'mp4',
-            'title': 'Arab wife want it so bad I see she thirsty and has tiny money.',
-            'thumbnail': None,
-            'view_count': int,
-            'age_limit': 18,
-        }
-    }, {
-        'url': 'http://www.keezmovies.com/video/18070681',
-        'only_matching': True,
-    }]
-
-    def _extract_info(self, url, fatal=True):
-        mobj = self._match_valid_url(url)
-        video_id = mobj.group('id')
-        display_id = (mobj.group('display_id')
-                      if 'display_id' in mobj.groupdict()
-                      else None) or mobj.group('id')
-
-        webpage = self._download_webpage(
-            url, display_id, headers={'Cookie': 'age_verified=1'})
-
-        formats = []
-        format_urls = set()
-
-        title = None
-        thumbnail = None
-        duration = None
-        encrypted = False
-
-        def extract_format(format_url, height=None):
-            format_url = url_or_none(format_url)
-            if not format_url or not format_url.startswith(('http', '//')):
-                return
-            if format_url in format_urls:
-                return
-            format_urls.add(format_url)
-            tbr = int_or_none(self._search_regex(
-                r'[/_](\d+)[kK][/_]', format_url, 'tbr', default=None))
-            if not height:
-                height = int_or_none(self._search_regex(
-                    r'[/_](\d+)[pP][/_]', format_url, 'height', default=None))
-            if encrypted:
-                format_url = aes_decrypt_text(
-                    video_url, title, 32).decode('utf-8')
-            formats.append({
-                'url': format_url,
-                'format_id': format_field(height, None, '%dp'),
-                'height': height,
-                'tbr': tbr,
-            })
-
-        flashvars = self._parse_json(
-            self._search_regex(
-                r'flashvars\s*=\s*({.+?});', webpage,
-                'flashvars', default='{}'),
-            display_id, fatal=False)
-
-        if flashvars:
-            title = flashvars.get('video_title')
-            thumbnail = flashvars.get('image_url')
-            duration = int_or_none(flashvars.get('video_duration'))
-            encrypted = flashvars.get('encrypted') is True
-            for key, value in flashvars.items():
-                mobj = re.search(r'quality_(\d+)[pP]', key)
-                if mobj:
-                    extract_format(value, int(mobj.group(1)))
-            video_url = flashvars.get('video_url')
-            if video_url and determine_ext(video_url, None):
-                extract_format(video_url)
-
-        video_url = self._html_search_regex(
-            r'flashvars\.video_url\s*=\s*(["\'])(?P<url>http.+?)\1',
-            webpage, 'video url', default=None, group='url')
-        if video_url:
-            extract_format(compat_urllib_parse_unquote(video_url))
-
-        if not formats:
-            if 'title="This video is no longer available"' in webpage:
-                self.raise_no_formats(
-                    'Video %s is no longer available' % video_id, expected=True)
-
-        if not title:
-            title = self._html_search_regex(
-                r'<h1[^>]*>([^<]+)', webpage, 'title')
-
-        return webpage, {
-            'id': video_id,
-            'display_id': display_id,
-            'title': strip_or_none(title),
-            'thumbnail': thumbnail,
-            'duration': duration,
-            'age_limit': 18,
-            'formats': formats,
-        }
-
-    def _real_extract(self, url):
-        webpage, info = self._extract_info(url, fatal=False)
-        if not info['formats']:
-            return self.url_result(url, 'Generic')
-        info['view_count'] = str_to_int(self._search_regex(
-            r'<b>([\d,.]+)</b> Views?', webpage, 'view count', fatal=False))
-        return info
index df1386fb86d261d44d0e12a89789e72c445c1b4a..a225d0a0d29f87f050f5ea98f7c2fc508560861c 100644 (file)
@@ -41,7 +41,6 @@ class KinjaEmbedIE(InfoExtractor):
             kinjavideo|
             mcp|
             megaphone|
             kinjavideo|
             mcp|
             megaphone|
-            ooyala|
             soundcloud(?:-playlist)?|
             tumblr-post|
             twitch-stream|
             soundcloud(?:-playlist)?|
             tumblr-post|
             twitch-stream|
@@ -61,9 +60,6 @@ class KinjaEmbedIE(InfoExtractor):
     }, {
         'url': 'https://kinja.com/ajax/inset/iframe?id=megaphone-PPY1300931075',
         'only_matching': True,
     }, {
         'url': 'https://kinja.com/ajax/inset/iframe?id=megaphone-PPY1300931075',
         'only_matching': True,
-    }, {
-        'url': 'https://kinja.com/ajax/inset/iframe?id=ooyala-xzMXhleDpopuT0u1ijt_qZj3Va-34pEX%2FZTIxYmJjZDM2NWYzZDViZGRiOWJjYzc5',
-        'only_matching': True,
     }, {
         'url': 'https://kinja.com/ajax/inset/iframe?id=soundcloud-128574047',
         'only_matching': True,
     }, {
         'url': 'https://kinja.com/ajax/inset/iframe?id=soundcloud-128574047',
         'only_matching': True,
@@ -103,7 +99,6 @@ class KinjaEmbedIE(InfoExtractor):
         'jwplayer-video': _JWPLATFORM_PROVIDER,
         'jwp-video': _JWPLATFORM_PROVIDER,
         'megaphone': ('player.megaphone.fm/', 'Generic'),
         'jwplayer-video': _JWPLATFORM_PROVIDER,
         'jwp-video': _JWPLATFORM_PROVIDER,
         'megaphone': ('player.megaphone.fm/', 'Generic'),
-        'ooyala': ('player.ooyala.com/player.js?embedCode=', 'Ooyala'),
         'soundcloud': ('api.soundcloud.com/tracks/', 'Soundcloud'),
         'soundcloud-playlist': ('api.soundcloud.com/playlists/', 'SoundcloudPlaylist'),
         'tumblr-post': ('%s.tumblr.com/post/%s', 'Tumblr'),
         'soundcloud': ('api.soundcloud.com/tracks/', 'Soundcloud'),
         'soundcloud-playlist': ('api.soundcloud.com/playlists/', 'SoundcloudPlaylist'),
         'tumblr-post': ('%s.tumblr.com/post/%s', 'Tumblr'),
@@ -129,8 +124,6 @@ def _real_extract(self, url):
                 video_id, playlist_id = video_id.split('/')
                 result_url = provider[0] % (video_id, playlist_id)
             else:
                 video_id, playlist_id = video_id.split('/')
                 result_url = provider[0] % (video_id, playlist_id)
             else:
-                if video_type == 'ooyala':
-                    video_id = video_id.split('/')[0]
                 result_url = provider[0] + video_id
             return self.url_result('http://' + result_url, provider[1])
 
                 result_url = provider[0] + video_id
             return self.url_result('http://' + result_url, provider[1])
 
diff --git a/yt_dlp/extractor/laola1tv.py b/yt_dlp/extractor/laola1tv.py
deleted file mode 100644 (file)
index 416dd7e..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-import json
-import re
-
-from .common import InfoExtractor
-from ..utils import (
-    ExtractorError,
-    unified_strdate,
-    urlencode_postdata,
-    xpath_element,
-    xpath_text,
-    update_url_query,
-    js_to_json,
-)
-
-
-class Laola1TvEmbedIE(InfoExtractor):
-    IE_NAME = 'laola1tv:embed'
-    _VALID_URL = r'https?://(?:www\.)?laola1\.tv/titanplayer\.php\?.*?\bvideoid=(?P<id>\d+)'
-    _TESTS = [{
-        # flashvars.premium = "false";
-        'url': 'https://www.laola1.tv/titanplayer.php?videoid=708065&type=V&lang=en&portal=int&customer=1024',
-        'info_dict': {
-            'id': '708065',
-            'ext': 'mp4',
-            'title': 'MA Long CHN - FAN Zhendong CHN',
-            'uploader': 'ITTF - International Table Tennis Federation',
-            'upload_date': '20161211',
-        },
-    }]
-
-    def _extract_token_url(self, stream_access_url, video_id, data):
-        return self._download_json(
-            self._proto_relative_url(stream_access_url, 'https:'), video_id,
-            headers={
-                'Content-Type': 'application/json',
-            }, data=json.dumps(data).encode())['data']['stream-access'][0]
-
-    def _extract_formats(self, token_url, video_id):
-        token_doc = self._download_xml(
-            token_url, video_id, 'Downloading token',
-            headers=self.geo_verification_headers())
-
-        token_attrib = xpath_element(token_doc, './/token').attrib
-
-        if token_attrib['status'] != '0':
-            raise ExtractorError(
-                'Token error: %s' % token_attrib['comment'], expected=True)
-
-        formats = self._extract_akamai_formats(
-            '%s?hdnea=%s' % (token_attrib['url'], token_attrib['auth']),
-            video_id)
-        return formats
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-        flash_vars = self._search_regex(
-            r'(?s)flashvars\s*=\s*({.+?});', webpage, 'flash vars')
-
-        def get_flashvar(x, *args, **kwargs):
-            flash_var = self._search_regex(
-                r'%s\s*:\s*"([^"]+)"' % x,
-                flash_vars, x, default=None)
-            if not flash_var:
-                flash_var = self._search_regex([
-                    r'flashvars\.%s\s*=\s*"([^"]+)"' % x,
-                    r'%s\s*=\s*"([^"]+)"' % x],
-                    webpage, x, *args, **kwargs)
-            return flash_var
-
-        hd_doc = self._download_xml(
-            'http://www.laola1.tv/server/hd_video.php', video_id, query={
-                'play': get_flashvar('streamid'),
-                'partner': get_flashvar('partnerid'),
-                'portal': get_flashvar('portalid'),
-                'lang': get_flashvar('sprache'),
-                'v5ident': '',
-            })
-
-        _v = lambda x, **k: xpath_text(hd_doc, './/video/' + x, **k)
-        title = _v('title', fatal=True)
-
-        token_url = None
-        premium = get_flashvar('premium', default=None)
-        if premium:
-            token_url = update_url_query(
-                _v('url', fatal=True), {
-                    'timestamp': get_flashvar('timestamp'),
-                    'auth': get_flashvar('auth'),
-                })
-        else:
-            data_abo = urlencode_postdata(
-                dict((i, v) for i, v in enumerate(_v('req_liga_abos').split(','))))
-            stream_access_url = update_url_query(
-                'https://club.laola1.tv/sp/laola1/api/v3/user/session/premium/player/stream-access', {
-                    'videoId': _v('id'),
-                    'target': self._search_regex(r'vs_target = (\d+);', webpage, 'vs target'),
-                    'label': _v('label'),
-                    'area': _v('area'),
-                })
-            token_url = self._extract_token_url(stream_access_url, video_id, data_abo)
-
-        formats = self._extract_formats(token_url, video_id)
-
-        categories_str = _v('meta_sports')
-        categories = categories_str.split(',') if categories_str else []
-        is_live = _v('islive') == 'true'
-
-        return {
-            'id': video_id,
-            'title': title,
-            'upload_date': unified_strdate(_v('time_date')),
-            'uploader': _v('meta_organisation'),
-            'categories': categories,
-            'is_live': is_live,
-            'formats': formats,
-        }
-
-
-class Laola1TvBaseIE(Laola1TvEmbedIE):  # XXX: Do not subclass from concrete IE
-    def _extract_video(self, url):
-        display_id = self._match_id(url)
-        webpage = self._download_webpage(url, display_id)
-
-        if 'Dieser Livestream ist bereits beendet.' in webpage:
-            raise ExtractorError('This live stream has already finished.', expected=True)
-
-        conf = self._parse_json(self._search_regex(
-            r'(?s)conf\s*=\s*({.+?});', webpage, 'conf'),
-            display_id,
-            transform_source=lambda s: js_to_json(re.sub(r'shareurl:.+,', '', s)))
-        video_id = conf['videoid']
-
-        config = self._download_json(conf['configUrl'], video_id, query={
-            'videoid': video_id,
-            'partnerid': conf['partnerid'],
-            'language': conf.get('language', ''),
-            'portal': conf.get('portalid', ''),
-        })
-        error = config.get('error')
-        if error:
-            raise ExtractorError('%s said: %s' % (self.IE_NAME, error), expected=True)
-
-        video_data = config['video']
-        title = video_data['title']
-        is_live = video_data.get('isLivestream') and video_data.get('isLive')
-        meta = video_data.get('metaInformation')
-        sports = meta.get('sports')
-        categories = sports.split(',') if sports else []
-
-        token_url = self._extract_token_url(
-            video_data['streamAccess'], video_id,
-            video_data['abo']['required'])
-
-        formats = self._extract_formats(token_url, video_id)
-
-        return {
-            'id': video_id,
-            'display_id': display_id,
-            'title': title,
-            'description': video_data.get('description'),
-            'thumbnail': video_data.get('image'),
-            'categories': categories,
-            'formats': formats,
-            'is_live': is_live,
-        }
-
-
-class Laola1TvIE(Laola1TvBaseIE):
-    IE_NAME = 'laola1tv'
-    _VALID_URL = r'https?://(?:www\.)?laola1\.tv/[a-z]+-[a-z]+/[^/]+/(?P<id>[^/?#&]+)'
-
-    _TESTS = [{
-        'url': 'http://www.laola1.tv/de-de/video/straubing-tigers-koelner-haie/227883.html',
-        'info_dict': {
-            'id': '227883',
-            'display_id': 'straubing-tigers-koelner-haie',
-            'ext': 'flv',
-            'title': 'Straubing Tigers - Kölner Haie',
-            'upload_date': '20140912',
-            'is_live': False,
-            'categories': ['Eishockey'],
-        },
-        'params': {
-            'skip_download': True,
-        },
-    }, {
-        'url': 'http://www.laola1.tv/de-de/video/straubing-tigers-koelner-haie',
-        'info_dict': {
-            'id': '464602',
-            'display_id': 'straubing-tigers-koelner-haie',
-            'ext': 'flv',
-            'title': 'Straubing Tigers - Kölner Haie',
-            'upload_date': '20160129',
-            'is_live': False,
-            'categories': ['Eishockey'],
-        },
-        'params': {
-            'skip_download': True,
-        },
-    }, {
-        'url': 'http://www.laola1.tv/de-de/livestream/2016-03-22-belogorie-belgorod-trentino-diatec-lde',
-        'info_dict': {
-            'id': '487850',
-            'display_id': '2016-03-22-belogorie-belgorod-trentino-diatec-lde',
-            'ext': 'flv',
-            'title': 'Belogorie BELGOROD - TRENTINO Diatec',
-            'upload_date': '20160322',
-            'uploader': 'CEV - Europäischer Volleyball Verband',
-            'is_live': True,
-            'categories': ['Volleyball'],
-        },
-        'params': {
-            'skip_download': True,
-        },
-        'skip': 'This live stream has already finished.',
-    }]
-
-    def _real_extract(self, url):
-        return self._extract_video(url)
-
-
-class EHFTVIE(Laola1TvBaseIE):
-    IE_NAME = 'ehftv'
-    _VALID_URL = r'https?://(?:www\.)?ehftv\.com/[a-z]+(?:-[a-z]+)?/[^/]+/(?P<id>[^/?#&]+)'
-
-    _TESTS = [{
-        'url': 'https://www.ehftv.com/int/video/paris-saint-germain-handball-pge-vive-kielce/1166761',
-        'info_dict': {
-            'id': '1166761',
-            'display_id': 'paris-saint-germain-handball-pge-vive-kielce',
-            'ext': 'mp4',
-            'title': 'Paris Saint-Germain Handball - PGE Vive Kielce',
-            'is_live': False,
-            'categories': ['Handball'],
-        },
-        'params': {
-            'skip_download': True,
-        },
-    }]
-
-    def _real_extract(self, url):
-        return self._extract_video(url)
-
-
-class ITTFIE(InfoExtractor):
-    _VALID_URL = r'https?://tv\.ittf\.com/video/[^/]+/(?P<id>\d+)'
-    _TEST = {
-        'url': 'https://tv.ittf.com/video/peng-wang-wei-matsudaira-kenta/951802',
-        'only_matching': True,
-    }
-
-    def _real_extract(self, url):
-        return self.url_result(
-            update_url_query('https://www.laola1.tv/titanplayer.php', {
-                'videoid': self._match_id(url),
-                'type': 'V',
-                'lang': 'en',
-                'portal': 'int',
-                'customer': 1024,
-            }), Laola1TvEmbedIE.ie_key())
diff --git a/yt_dlp/extractor/linuxacademy.py b/yt_dlp/extractor/linuxacademy.py
deleted file mode 100644 (file)
index 0b16442..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-import json
-import random
-
-from .common import InfoExtractor
-from ..compat import compat_b64decode, compat_str
-from ..networking.exceptions import HTTPError
-from ..utils import (
-    clean_html,
-    ExtractorError,
-    js_to_json,
-    parse_duration,
-    try_get,
-    unified_timestamp,
-    urlencode_postdata,
-    urljoin,
-)
-
-
-class LinuxAcademyIE(InfoExtractor):
-    _VALID_URL = r'''(?x)
-                    https?://
-                        (?:www\.)?linuxacademy\.com/cp/
-                        (?:
-                            courses/lesson/course/(?P<chapter_id>\d+)/lesson/(?P<lesson_id>\d+)|
-                            modules/view/id/(?P<course_id>\d+)
-                        )
-                    '''
-    _TESTS = [{
-        'url': 'https://linuxacademy.com/cp/courses/lesson/course/7971/lesson/2/module/675',
-        'info_dict': {
-            'id': '7971-2',
-            'ext': 'mp4',
-            'title': 'What Is Data Science',
-            'description': 'md5:c574a3c20607144fb36cb65bdde76c99',
-            'timestamp': int,  # The timestamp and upload date changes
-            'upload_date': r're:\d+',
-            'duration': 304,
-        },
-        'params': {
-            'skip_download': True,
-        },
-        'skip': 'Requires Linux Academy account credentials',
-    }, {
-        'url': 'https://linuxacademy.com/cp/courses/lesson/course/1498/lesson/2',
-        'only_matching': True,
-    }, {
-        'url': 'https://linuxacademy.com/cp/modules/view/id/154',
-        'info_dict': {
-            'id': '154',
-            'title': 'AWS Certified Cloud Practitioner',
-            'description': 'md5:a68a299ca9bb98d41cca5abc4d4ce22c',
-            'duration': 28835,
-        },
-        'playlist_count': 41,
-        'skip': 'Requires Linux Academy account credentials',
-    }, {
-        'url': 'https://linuxacademy.com/cp/modules/view/id/39',
-        'info_dict': {
-            'id': '39',
-            'title': 'Red Hat Certified Systems Administrator - RHCSA (EX200) Exam Prep  (legacy)',
-            'description': 'md5:0f1d3369e90c3fb14a79813b863c902f',
-            'duration': 89280,
-        },
-        'playlist_count': 73,
-        'skip': 'Requires Linux Academy account credentials',
-    }]
-
-    _AUTHORIZE_URL = 'https://login.linuxacademy.com/authorize'
-    _ORIGIN_URL = 'https://linuxacademy.com'
-    _CLIENT_ID = 'KaWxNn1C2Gc7n83W9OFeXltd8Utb5vvx'
-    _NETRC_MACHINE = 'linuxacademy'
-
-    def _perform_login(self, username, password):
-        def random_string():
-            return ''.join(random.choices(
-                '0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._~', k=32))
-
-        webpage, urlh = self._download_webpage_handle(
-            self._AUTHORIZE_URL, None, 'Downloading authorize page', query={
-                'client_id': self._CLIENT_ID,
-                'response_type': 'token id_token',
-                'response_mode': 'web_message',
-                'redirect_uri': self._ORIGIN_URL,
-                'scope': 'openid email user_impersonation profile',
-                'audience': self._ORIGIN_URL,
-                'state': random_string(),
-                'nonce': random_string(),
-            })
-
-        login_data = self._parse_json(
-            self._search_regex(
-                r'atob\(\s*(["\'])(?P<value>(?:(?!\1).)+)\1', webpage,
-                'login info', group='value'), None,
-            transform_source=lambda x: compat_b64decode(x).decode('utf-8')
-        )['extraParams']
-
-        login_data.update({
-            'client_id': self._CLIENT_ID,
-            'redirect_uri': self._ORIGIN_URL,
-            'tenant': 'lacausers',
-            'connection': 'Username-Password-ACG-Proxy',
-            'username': username,
-            'password': password,
-            'sso': 'true',
-        })
-
-        login_state_url = urlh.url
-
-        try:
-            login_page = self._download_webpage(
-                'https://login.linuxacademy.com/usernamepassword/login', None,
-                'Downloading login page', data=json.dumps(login_data).encode(),
-                headers={
-                    'Content-Type': 'application/json',
-                    'Origin': 'https://login.linuxacademy.com',
-                    'Referer': login_state_url,
-                })
-        except ExtractorError as e:
-            if isinstance(e.cause, HTTPError) and e.cause.status == 401:
-                error = self._parse_json(e.cause.response.read(), None)
-                message = error.get('description') or error['code']
-                raise ExtractorError(
-                    '%s said: %s' % (self.IE_NAME, message), expected=True)
-            raise
-
-        callback_page, urlh = self._download_webpage_handle(
-            'https://login.linuxacademy.com/login/callback', None,
-            'Downloading callback page',
-            data=urlencode_postdata(self._hidden_inputs(login_page)),
-            headers={
-                'Content-Type': 'application/x-www-form-urlencoded',
-                'Origin': 'https://login.linuxacademy.com',
-                'Referer': login_state_url,
-            })
-
-        access_token = self._search_regex(
-            r'access_token=([^=&]+)', urlh.url,
-            'access token', default=None)
-        if not access_token:
-            access_token = self._parse_json(
-                self._search_regex(
-                    r'authorizationResponse\s*=\s*({.+?})\s*;', callback_page,
-                    'authorization response'), None,
-                transform_source=js_to_json)['response']['access_token']
-
-        self._download_webpage(
-            'https://linuxacademy.com/cp/login/tokenValidateLogin/token/%s'
-            % access_token, None, 'Downloading token validation page')
-
-    def _real_extract(self, url):
-        mobj = self._match_valid_url(url)
-        chapter_id, lecture_id, course_id = mobj.group('chapter_id', 'lesson_id', 'course_id')
-        item_id = course_id if course_id else '%s-%s' % (chapter_id, lecture_id)
-
-        webpage = self._download_webpage(url, item_id)
-
-        # course path
-        if course_id:
-            module = self._parse_json(
-                self._search_regex(
-                    r'window\.module\s*=\s*({(?:(?!};)[^"]|"([^"]|\\")*")+})\s*;', webpage, 'module'),
-                item_id)
-            entries = []
-            chapter_number = None
-            chapter = None
-            chapter_id = None
-            for item in module['items']:
-                if not isinstance(item, dict):
-                    continue
-
-                def type_field(key):
-                    return (try_get(item, lambda x: x['type'][key], compat_str) or '').lower()
-                type_fields = (type_field('name'), type_field('slug'))
-                # Move to next module section
-                if 'section' in type_fields:
-                    chapter = item.get('course_name')
-                    chapter_id = item.get('course_module')
-                    chapter_number = 1 if not chapter_number else chapter_number + 1
-                    continue
-                # Skip non-lessons
-                if 'lesson' not in type_fields:
-                    continue
-                lesson_url = urljoin(url, item.get('url'))
-                if not lesson_url:
-                    continue
-                title = item.get('title') or item.get('lesson_name')
-                description = item.get('md_desc') or clean_html(item.get('description')) or clean_html(item.get('text'))
-                entries.append({
-                    '_type': 'url_transparent',
-                    'url': lesson_url,
-                    'ie_key': LinuxAcademyIE.ie_key(),
-                    'title': title,
-                    'description': description,
-                    'timestamp': unified_timestamp(item.get('date')) or unified_timestamp(item.get('created_on')),
-                    'duration': parse_duration(item.get('duration')),
-                    'chapter': chapter,
-                    'chapter_id': chapter_id,
-                    'chapter_number': chapter_number,
-                })
-            return {
-                '_type': 'playlist',
-                'entries': entries,
-                'id': course_id,
-                'title': module.get('title'),
-                'description': module.get('md_desc') or clean_html(module.get('desc')),
-                'duration': parse_duration(module.get('duration')),
-            }
-
-        # single video path
-        m3u8_url = self._parse_json(
-            self._search_regex(
-                r'player\.playlist\s*=\s*(\[.+?\])\s*;', webpage, 'playlist'),
-            item_id)[0]['file']
-        formats = self._extract_m3u8_formats(
-            m3u8_url, item_id, 'mp4', entry_protocol='m3u8_native',
-            m3u8_id='hls')
-        info = {
-            'id': item_id,
-            'formats': formats,
-        }
-        lesson = self._parse_json(
-            self._search_regex(
-                (r'window\.lesson\s*=\s*({.+?})\s*;',
-                 r'player\.lesson\s*=\s*({.+?})\s*;'),
-                webpage, 'lesson', default='{}'), item_id, fatal=False)
-        if lesson:
-            info.update({
-                'title': lesson.get('lesson_name'),
-                'description': lesson.get('md_desc') or clean_html(lesson.get('desc')),
-                'timestamp': unified_timestamp(lesson.get('date')) or unified_timestamp(lesson.get('created_on')),
-                'duration': parse_duration(lesson.get('duration')),
-            })
-        if not info.get('title'):
-            info['title'] = self._search_regex(
-                (r'>Lecture\s*:\s*(?P<value>[^<]+)',
-                 r'lessonName\s*=\s*(["\'])(?P<value>(?:(?!\1).)+)\1'), webpage,
-                'title', group='value')
-        return info
diff --git a/yt_dlp/extractor/m6.py b/yt_dlp/extractor/m6.py
deleted file mode 100644 (file)
index 9dcc601..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from .common import InfoExtractor
-
-
-class M6IE(InfoExtractor):
-    IE_NAME = 'm6'
-    _VALID_URL = r'https?://(?:www\.)?m6\.fr/[^/]+/videos/(?P<id>\d+)-[^\.]+\.html'
-
-    _TEST = {
-        'url': 'http://www.m6.fr/emission-les_reines_du_shopping/videos/11323908-emeline_est_la_reine_du_shopping_sur_le_theme_ma_fete_d_8217_anniversaire.html',
-        'md5': '242994a87de2c316891428e0176bcb77',
-        'info_dict': {
-            'id': '11323908',
-            'ext': 'mp4',
-            'title': 'Emeline est la Reine du Shopping sur le thème « Ma fête d’anniversaire ! »',
-            'description': 'md5:1212ae8fb4b7baa4dc3886c5676007c2',
-            'duration': 100,
-        }
-    }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        return self.url_result('6play:%s' % video_id, 'SixPlay', video_id)
diff --git a/yt_dlp/extractor/meta.py b/yt_dlp/extractor/meta.py
deleted file mode 100644 (file)
index 7c11e60..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-from .common import InfoExtractor
-from .pladform import PladformIE
-from ..utils import (
-    unescapeHTML,
-    int_or_none,
-    ExtractorError,
-)
-
-
-class METAIE(InfoExtractor):
-    _VALID_URL = r'https?://video\.meta\.ua/(?:iframe/)?(?P<id>[0-9]+)'
-    _TESTS = [{
-        'url': 'http://video.meta.ua/5502115.video',
-        'md5': '71b6f3ee274bef16f1ab410f7f56b476',
-        'info_dict': {
-            'id': '5502115',
-            'ext': 'mp4',
-            'title': 'Sony Xperia Z camera test [HQ]',
-            'description': 'Xperia Z shoots video in FullHD HDR.',
-            'uploader_id': 'nomobile',
-            'uploader': 'CHЁZA.TV',
-            'upload_date': '20130211',
-        },
-        'add_ie': ['Youtube'],
-    }, {
-        'url': 'http://video.meta.ua/iframe/5502115',
-        'only_matching': True,
-    }, {
-        # pladform embed
-        'url': 'http://video.meta.ua/7121015.video',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-
-        st_html5 = self._search_regex(
-            r"st_html5\s*=\s*'#([^']+)'", webpage, 'uppod html5 st', default=None)
-
-        if st_html5:
-            # uppod st decryption algorithm is reverse engineered from function un(s) at uppod.js
-            json_str = ''
-            for i in range(0, len(st_html5), 3):
-                json_str += '&#x0%s;' % st_html5[i:i + 3]
-            uppod_data = self._parse_json(unescapeHTML(json_str), video_id)
-            error = uppod_data.get('customnotfound')
-            if error:
-                raise ExtractorError('%s said: %s' % (self.IE_NAME, error), expected=True)
-
-            video_url = uppod_data['file']
-            info = {
-                'id': video_id,
-                'url': video_url,
-                'title': uppod_data.get('comment') or self._og_search_title(webpage),
-                'description': self._og_search_description(webpage, default=None),
-                'thumbnail': uppod_data.get('poster') or self._og_search_thumbnail(webpage),
-                'duration': int_or_none(self._og_search_property(
-                    'video:duration', webpage, default=None)),
-            }
-            if 'youtube.com/' in video_url:
-                info.update({
-                    '_type': 'url_transparent',
-                    'ie_key': 'Youtube',
-                })
-            return info
-
-        pladform_url = PladformIE._extract_url(webpage)
-        if pladform_url:
-            return self.url_result(pladform_url)
diff --git a/yt_dlp/extractor/metacafe.py b/yt_dlp/extractor/metacafe.py
deleted file mode 100644 (file)
index d7f5def..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-import json
-import re
-import urllib.parse
-
-from .common import InfoExtractor
-from ..compat import compat_parse_qs, compat_urllib_parse_unquote
-from ..utils import (
-    ExtractorError,
-    determine_ext,
-    get_element_by_attribute,
-    int_or_none,
-    mimetype2ext,
-)
-
-
-class MetacafeIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?metacafe\.com/watch/(?P<id>[^/]+)/(?P<display_id>[^/?#]+)'
-    _DISCLAIMER = 'http://www.metacafe.com/family_filter/'
-    _FILTER_POST = 'http://www.metacafe.com/f/index.php?inputType=filter&controllerGroup=user'
-    IE_NAME = 'metacafe'
-    _TESTS = [
-        # Youtube video
-        {
-            'add_ie': ['Youtube'],
-            'url': 'http://metacafe.com/watch/yt-_aUehQsCQtM/the_electric_company_short_i_pbs_kids_go/',
-            'info_dict': {
-                'id': '_aUehQsCQtM',
-                'ext': 'mp4',
-                'upload_date': '20090102',
-                'title': 'The Electric Company | "Short I" | PBS KIDS GO!',
-                'description': 'md5:2439a8ef6d5a70e380c22f5ad323e5a8',
-                'uploader': 'PBS',
-                'uploader_id': 'PBS'
-            }
-        },
-        # Normal metacafe video
-        {
-            'url': 'http://www.metacafe.com/watch/11121940/news_stuff_you_wont_do_with_your_playstation_4/',
-            'md5': '6e0bca200eaad2552e6915ed6fd4d9ad',
-            'info_dict': {
-                'id': '11121940',
-                'ext': 'mp4',
-                'title': 'News: Stuff You Won\'t Do with Your PlayStation 4',
-                'uploader': 'ign',
-                'description': 'Sony released a massive FAQ on the PlayStation Blog detailing the PS4\'s capabilities and limitations.',
-            },
-            'skip': 'Page is temporarily unavailable.',
-        },
-        # metacafe video with family filter
-        {
-            'url': 'http://www.metacafe.com/watch/2155630/adult_art_by_david_hart_156/',
-            'md5': 'b06082c5079bbdcde677a6291fbdf376',
-            'info_dict': {
-                'id': '2155630',
-                'ext': 'mp4',
-                'title': 'Adult Art By David Hart 156',
-                'uploader': '63346',
-                'description': 'md5:9afac8fc885252201ad14563694040fc',
-            },
-            'params': {
-                'skip_download': True,
-            },
-        },
-        # AnyClip video
-        {
-            'url': 'http://www.metacafe.com/watch/an-dVVXnuY7Jh77J/the_andromeda_strain_1971_stop_the_bomb_part_3/',
-            'info_dict': {
-                'id': 'an-dVVXnuY7Jh77J',
-                'ext': 'mp4',
-                'title': 'The Andromeda Strain (1971): Stop the Bomb Part 3',
-                'uploader': 'AnyClip',
-                'description': 'md5:cbef0460d31e3807f6feb4e7a5952e5b',
-            },
-        },
-        # age-restricted video
-        {
-            'url': 'http://www.metacafe.com/watch/5186653/bbc_internal_christmas_tape_79_uncensored_outtakes_etc/',
-            'md5': '98dde7c1a35d02178e8ab7560fe8bd09',
-            'info_dict': {
-                'id': '5186653',
-                'ext': 'mp4',
-                'title': 'BBC INTERNAL Christmas Tape \'79 - UNCENSORED Outtakes, Etc.',
-                'uploader': 'Dwayne Pipe',
-                'description': 'md5:950bf4c581e2c059911fa3ffbe377e4b',
-                'age_limit': 18,
-            },
-        },
-        # cbs video
-        {
-            'url': 'http://www.metacafe.com/watch/cb-8VD4r_Zws8VP/open_this_is_face_the_nation_february_9/',
-            'info_dict': {
-                'id': '8VD4r_Zws8VP',
-                'ext': 'flv',
-                'title': 'Open: This is Face the Nation, February 9',
-                'description': 'md5:8a9ceec26d1f7ed6eab610834cc1a476',
-                'duration': 96,
-                'uploader': 'CBSI-NEW',
-                'upload_date': '20140209',
-                'timestamp': 1391959800,
-            },
-            'params': {
-                # rtmp download
-                'skip_download': True,
-            },
-        },
-        # Movieclips.com video
-        {
-            'url': 'http://www.metacafe.com/watch/mv-Wy7ZU/my_week_with_marilyn_do_you_love_me/',
-            'info_dict': {
-                'id': 'mv-Wy7ZU',
-                'ext': 'mp4',
-                'title': 'My Week with Marilyn - Do You Love Me?',
-                'description': 'From the movie My Week with Marilyn - Colin (Eddie Redmayne) professes his love to Marilyn (Michelle Williams) and gets her to promise to return to set and finish the movie.',
-                'uploader': 'movie_trailers',
-                'duration': 176,
-            },
-            'params': {
-                'skip_download': 'requires rtmpdump',
-            }
-        }
-    ]
-
-    def report_disclaimer(self):
-        self.to_screen('Retrieving disclaimer')
-
-    def _real_extract(self, url):
-        # Extract id and simplified title from URL
-        video_id, display_id = self._match_valid_url(url).groups()
-
-        # the video may come from an external site
-        m_external = re.match(r'^(\w{2})-(.*)$', video_id)
-        if m_external is not None:
-            prefix, ext_id = m_external.groups()
-            # Check if video comes from YouTube
-            if prefix == 'yt':
-                return self.url_result('http://www.youtube.com/watch?v=%s' % ext_id, 'Youtube')
-            # CBS videos use theplatform.com
-            if prefix == 'cb':
-                return self.url_result('theplatform:%s' % ext_id, 'ThePlatform')
-
-        headers = {
-            # Disable family filter
-            'Cookie': 'user=%s; ' % urllib.parse.quote(json.dumps({'ffilter': False}))
-        }
-
-        # AnyClip videos require the flashversion cookie so that we get the link
-        # to the mp4 file
-        if video_id.startswith('an-'):
-            headers['Cookie'] += 'flashVersion=0; '
-
-        # Retrieve video webpage to extract further information
-        webpage = self._download_webpage(url, video_id, headers=headers)
-
-        error = get_element_by_attribute(
-            'class', 'notfound-page-title', webpage)
-        if error:
-            raise ExtractorError(error, expected=True)
-
-        video_title = self._html_search_meta(
-            ['og:title', 'twitter:title'], webpage, 'title', default=None) or self._search_regex(r'<h1>(.*?)</h1>', webpage, 'title')
-
-        # Extract URL, uploader and title from webpage
-        self.report_extraction(video_id)
-        video_url = None
-        mobj = re.search(r'(?m)&(?:media|video)URL=([^&]+)', webpage)
-        if mobj is not None:
-            mediaURL = compat_urllib_parse_unquote(mobj.group(1))
-            video_ext = determine_ext(mediaURL)
-
-            # Extract gdaKey if available
-            mobj = re.search(r'(?m)&gdaKey=(.*?)&', webpage)
-            if mobj is None:
-                video_url = mediaURL
-            else:
-                gdaKey = mobj.group(1)
-                video_url = '%s?__gda__=%s' % (mediaURL, gdaKey)
-        if video_url is None:
-            mobj = re.search(r'<video src="([^"]+)"', webpage)
-            if mobj:
-                video_url = mobj.group(1)
-                video_ext = 'mp4'
-        if video_url is None:
-            flashvars = self._search_regex(
-                r' name="flashvars" value="(.*?)"', webpage, 'flashvars',
-                default=None)
-            if flashvars:
-                vardict = compat_parse_qs(flashvars)
-                if 'mediaData' not in vardict:
-                    raise ExtractorError('Unable to extract media URL')
-                mobj = re.search(
-                    r'"mediaURL":"(?P<mediaURL>http.*?)",(.*?)"key":"(?P<key>.*?)"', vardict['mediaData'][0])
-                if mobj is None:
-                    raise ExtractorError('Unable to extract media URL')
-                mediaURL = mobj.group('mediaURL').replace('\\/', '/')
-                video_url = '%s?__gda__=%s' % (mediaURL, mobj.group('key'))
-                video_ext = determine_ext(video_url)
-        if video_url is None:
-            player_url = self._search_regex(
-                r"swfobject\.embedSWF\('([^']+)'",
-                webpage, 'config URL', default=None)
-            if player_url:
-                config_url = self._search_regex(
-                    r'config=(.+)$', player_url, 'config URL')
-                config_doc = self._download_xml(
-                    config_url, video_id,
-                    note='Downloading video config')
-                smil_url = config_doc.find('.//properties').attrib['smil_file']
-                smil_doc = self._download_xml(
-                    smil_url, video_id,
-                    note='Downloading SMIL document')
-                base_url = smil_doc.find('./head/meta').attrib['base']
-                video_url = []
-                for vn in smil_doc.findall('.//video'):
-                    br = int(vn.attrib['system-bitrate'])
-                    play_path = vn.attrib['src']
-                    video_url.append({
-                        'format_id': 'smil-%d' % br,
-                        'url': base_url,
-                        'play_path': play_path,
-                        'page_url': url,
-                        'player_url': player_url,
-                        'ext': play_path.partition(':')[0],
-                    })
-        if video_url is None:
-            flashvars = self._parse_json(self._search_regex(
-                r'flashvars\s*=\s*({.*});', webpage, 'flashvars',
-                default=None), video_id, fatal=False)
-            if flashvars:
-                video_url = []
-                for source in flashvars.get('sources'):
-                    source_url = source.get('src')
-                    if not source_url:
-                        continue
-                    ext = mimetype2ext(source.get('type')) or determine_ext(source_url)
-                    if ext == 'm3u8':
-                        video_url.extend(self._extract_m3u8_formats(
-                            source_url, video_id, 'mp4',
-                            'm3u8_native', m3u8_id='hls', fatal=False))
-                    else:
-                        video_url.append({
-                            'url': source_url,
-                            'ext': ext,
-                        })
-
-        if video_url is None:
-            raise ExtractorError('Unsupported video type')
-
-        description = self._html_search_meta(
-            ['og:description', 'twitter:description', 'description'],
-            webpage, 'title', fatal=False)
-        thumbnail = self._html_search_meta(
-            ['og:image', 'twitter:image'], webpage, 'title', fatal=False)
-        video_uploader = self._html_search_regex(
-            r'submitter=(.*?);|googletag\.pubads\(\)\.setTargeting\("(?:channel|submiter)","([^"]+)"\);',
-            webpage, 'uploader nickname', fatal=False)
-        duration = int_or_none(
-            self._html_search_meta('video:duration', webpage, default=None))
-        age_limit = (
-            18
-            if re.search(r'(?:"contentRating":|"rating",)"restricted"', webpage)
-            else 0)
-
-        if isinstance(video_url, list):
-            formats = video_url
-        else:
-            formats = [{
-                'url': video_url,
-                'ext': video_ext,
-            }]
-
-        return {
-            'id': video_id,
-            'display_id': display_id,
-            'description': description,
-            'uploader': video_uploader,
-            'title': video_title,
-            'thumbnail': thumbnail,
-            'age_limit': age_limit,
-            'formats': formats,
-            'duration': duration,
-        }
diff --git a/yt_dlp/extractor/mgoon.py b/yt_dlp/extractor/mgoon.py
deleted file mode 100644 (file)
index 2388a71..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    ExtractorError,
-    qualities,
-    unified_strdate,
-)
-
-
-class MgoonIE(InfoExtractor):
-    _VALID_URL = r'''(?x)https?://(?:www\.)?
-    (?:(:?m\.)?mgoon\.com/(?:ch/(?:.+)/v|play/view)|
-        video\.mgoon\.com)/(?P<id>[0-9]+)'''
-    _API_URL = 'http://mpos.mgoon.com/player/video?id={0:}'
-    _TESTS = [
-        {
-            'url': 'http://m.mgoon.com/ch/hi6618/v/5582148',
-            'md5': 'dd46bb66ab35cf6d51cc812fd82da79d',
-            'info_dict': {
-                'id': '5582148',
-                'uploader_id': 'hi6618',
-                'duration': 240.419,
-                'upload_date': '20131220',
-                'ext': 'mp4',
-                'title': 'md5:543aa4c27a4931d371c3f433e8cebebc',
-                'thumbnail': r're:^https?://.*\.jpg$',
-            }
-        },
-        {
-            'url': 'http://www.mgoon.com/play/view/5582148',
-            'only_matching': True,
-        },
-        {
-            'url': 'http://video.mgoon.com/5582148',
-            'only_matching': True,
-        },
-    ]
-
-    def _real_extract(self, url):
-        mobj = self._match_valid_url(url)
-        video_id = mobj.group('id')
-
-        data = self._download_json(self._API_URL.format(video_id), video_id)
-
-        if data.get('errorInfo', {}).get('code') != 'NONE':
-            raise ExtractorError('%s encountered an error: %s' % (
-                self.IE_NAME, data['errorInfo']['message']), expected=True)
-
-        v_info = data['videoInfo']
-        title = v_info.get('v_title')
-        thumbnail = v_info.get('v_thumbnail')
-        duration = v_info.get('v_duration')
-        upload_date = unified_strdate(v_info.get('v_reg_date'))
-        uploader_id = data.get('userInfo', {}).get('u_alias')
-        if duration:
-            duration /= 1000.0
-
-        age_limit = None
-        if data.get('accessInfo', {}).get('code') == 'VIDEO_STATUS_ADULT':
-            age_limit = 18
-
-        formats = []
-        get_quality = qualities(['360p', '480p', '720p', '1080p'])
-        for fmt in data['videoFiles']:
-            formats.append({
-                'format_id': fmt['label'],
-                'quality': get_quality(fmt['label']),
-                'url': fmt['url'],
-                'ext': fmt['format'],
-
-            })
-
-        return {
-            'id': video_id,
-            'title': title,
-            'formats': formats,
-            'thumbnail': thumbnail,
-            'duration': duration,
-            'upload_date': upload_date,
-            'uploader_id': uploader_id,
-            'age_limit': age_limit,
-        }
diff --git a/yt_dlp/extractor/miomio.py b/yt_dlp/extractor/miomio.py
deleted file mode 100644 (file)
index 8df8cba..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-import random
-
-from .common import InfoExtractor
-from ..compat import compat_urlparse
-from ..networking import Request
-from ..utils import ExtractorError, int_or_none, xpath_text
-
-
-class MioMioIE(InfoExtractor):
-    IE_NAME = 'miomio.tv'
-    _VALID_URL = r'https?://(?:www\.)?miomio\.tv/watch/cc(?P<id>[0-9]+)'
-    _TESTS = [{
-        # "type=video" in flashvars
-        'url': 'http://www.miomio.tv/watch/cc88912/',
-        'info_dict': {
-            'id': '88912',
-            'ext': 'flv',
-            'title': '【SKY】字幕 铠武昭和VS平成 假面骑士大战FEAT战队 魔星字幕组 字幕',
-            'duration': 5923,
-        },
-        'skip': 'Unable to load videos',
-    }, {
-        'url': 'http://www.miomio.tv/watch/cc184024/',
-        'info_dict': {
-            'id': '43729',
-            'title': '《动漫同人插画绘制》',
-        },
-        'playlist_mincount': 86,
-        'skip': 'Unable to load videos',
-    }, {
-        'url': 'http://www.miomio.tv/watch/cc173113/',
-        'info_dict': {
-            'id': '173113',
-            'title': 'The New Macbook 2015 上手试玩与简评'
-        },
-        'playlist_mincount': 2,
-        'skip': 'Unable to load videos',
-    }, {
-        # new 'h5' player
-        'url': 'http://www.miomio.tv/watch/cc273997/',
-        'md5': '0b27a4b4495055d826813f8c3a6b2070',
-        'info_dict': {
-            'id': '273997',
-            'ext': 'mp4',
-            'title': 'マツコの知らない世界【劇的進化SP!ビニール傘&冷凍食品2016】 1_2 - 16 05 31',
-        },
-        'skip': 'Unable to load videos',
-    }]
-
-    def _extract_mioplayer(self, webpage, video_id, title, http_headers):
-        xml_config = self._search_regex(
-            r'flashvars="type=(?:sina|video)&amp;(.+?)&amp;',
-            webpage, 'xml config')
-
-        # skipping the following page causes lags and eventually connection drop-outs
-        self._request_webpage(
-            'http://www.miomio.tv/mioplayer/mioplayerconfigfiles/xml.php?id=%s&r=%s' % (id, random.randint(100, 999)),
-            video_id)
-
-        vid_config_request = Request(
-            'http://www.miomio.tv/mioplayer/mioplayerconfigfiles/sina.php?{0}'.format(xml_config),
-            headers=http_headers)
-
-        # the following xml contains the actual configuration information on the video file(s)
-        vid_config = self._download_xml(vid_config_request, video_id)
-
-        if not int_or_none(xpath_text(vid_config, 'timelength')):
-            raise ExtractorError('Unable to load videos!', expected=True)
-
-        entries = []
-        for f in vid_config.findall('./durl'):
-            segment_url = xpath_text(f, 'url', 'video url')
-            if not segment_url:
-                continue
-            order = xpath_text(f, 'order', 'order')
-            segment_id = video_id
-            segment_title = title
-            if order:
-                segment_id += '-%s' % order
-                segment_title += ' part %s' % order
-            entries.append({
-                'id': segment_id,
-                'url': segment_url,
-                'title': segment_title,
-                'duration': int_or_none(xpath_text(f, 'length', 'duration'), 1000),
-                'http_headers': http_headers,
-            })
-
-        return entries
-
-    def _download_chinese_webpage(self, *args, **kwargs):
-        # Requests with English locales return garbage
-        headers = {
-            'Accept-Language': 'zh-TW,en-US;q=0.7,en;q=0.3',
-        }
-        kwargs.setdefault('headers', {}).update(headers)
-        return self._download_webpage(*args, **kwargs)
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_chinese_webpage(
-            url, video_id)
-
-        title = self._html_search_meta(
-            'description', webpage, 'title', fatal=True)
-
-        mioplayer_path = self._search_regex(
-            r'src="(/mioplayer(?:_h5)?/[^"]+)"', webpage, 'ref_path')
-
-        if '_h5' in mioplayer_path:
-            player_url = compat_urlparse.urljoin(url, mioplayer_path)
-            player_webpage = self._download_chinese_webpage(
-                player_url, video_id,
-                note='Downloading player webpage', headers={'Referer': url})
-            entries = self._parse_html5_media_entries(player_url, player_webpage, video_id)
-            http_headers = {'Referer': player_url}
-        else:
-            http_headers = {'Referer': 'http://www.miomio.tv%s' % mioplayer_path}
-            entries = self._extract_mioplayer(webpage, video_id, title, http_headers)
-
-        if len(entries) == 1:
-            segment = entries[0]
-            segment['id'] = video_id
-            segment['title'] = title
-            segment['http_headers'] = http_headers
-            return segment
-
-        return {
-            '_type': 'multi_video',
-            'id': video_id,
-            'entries': entries,
-            'title': title,
-            'http_headers': http_headers,
-        }
diff --git a/yt_dlp/extractor/mnet.py b/yt_dlp/extractor/mnet.py
deleted file mode 100644 (file)
index 98bab2e..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    int_or_none,
-    parse_duration,
-    parse_iso8601,
-)
-
-
-class MnetIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?mnet\.(?:com|interest\.me)/tv/vod/(?:.*?\bclip_id=)?(?P<id>[0-9]+)'
-    _TESTS = [{
-        'url': 'http://www.mnet.com/tv/vod/171008',
-        'info_dict': {
-            'id': '171008',
-            'title': 'SS_이해인@히든박스',
-            'description': 'md5:b9efa592c3918b615ba69fe9f8a05c55',
-            'duration': 88,
-            'upload_date': '20151231',
-            'timestamp': 1451564040,
-            'age_limit': 0,
-            'thumbnails': 'mincount:5',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'ext': 'flv',
-        },
-        'params': {
-            # rtmp download
-            'skip_download': True,
-        },
-    }, {
-        'url': 'http://mnet.interest.me/tv/vod/172790',
-        'only_matching': True,
-    }, {
-        'url': 'http://www.mnet.com/tv/vod/vod_view.asp?clip_id=172790&tabMenu=',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        # TODO: extract rtmp formats
-        # no stype -> rtmp url
-        # stype=H -> m3u8 url
-        # stype=M -> mpd url
-        info = self._download_json(
-            'http://content.api.mnet.com/player/vodConfig',
-            video_id, 'Downloading vod config JSON', query={
-                'id': video_id,
-                'ctype': 'CLIP',
-                'stype': 'H',
-            })['data']['info']
-
-        title = info['title']
-
-        cdn_data = self._download_json(
-            info['cdn'], video_id, 'Downloading vod cdn JSON')['data'][0]
-        m3u8_url = cdn_data['url']
-        token = cdn_data.get('token')
-        if token and token != '-':
-            m3u8_url += '?' + token
-        formats = self._extract_wowza_formats(
-            m3u8_url, video_id, skip_protocols=['rtmp', 'rtsp', 'f4m'])
-
-        description = info.get('ment')
-        duration = parse_duration(info.get('time'))
-        timestamp = parse_iso8601(info.get('date'), delimiter=' ')
-        age_limit = info.get('adult')
-        if age_limit is not None:
-            age_limit = 0 if age_limit == 'N' else 18
-        thumbnails = [{
-            'id': thumb_format,
-            'url': thumb['url'],
-            'width': int_or_none(thumb.get('width')),
-            'height': int_or_none(thumb.get('height')),
-        } for thumb_format, thumb in info.get('cover', {}).items() if thumb.get('url')]
-
-        return {
-            'id': video_id,
-            'title': title,
-            'description': description,
-            'duration': duration,
-            'timestamp': timestamp,
-            'age_limit': age_limit,
-            'thumbnails': thumbnails,
-            'formats': formats,
-        }
diff --git a/yt_dlp/extractor/moevideo.py b/yt_dlp/extractor/moevideo.py
deleted file mode 100644 (file)
index fda08ca..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    clean_html,
-    int_or_none,
-)
-
-
-class MoeVideoIE(InfoExtractor):
-    IE_DESC = 'LetitBit video services: moevideo.net, playreplay.net and videochart.net'
-    _VALID_URL = r'''(?x)
-        https?://(?P<host>(?:www\.)?
-        (?:(?:moevideo|playreplay|videochart)\.net|thesame\.tv))/
-        (?:video|framevideo|embed)/(?P<id>[0-9a-z]+\.[0-9A-Za-z]+)'''
-    _API_URL = 'http://api.letitbit.net/'
-    _API_KEY = 'tVL0gjqo5'
-    _TESTS = [
-        {
-            'url': 'http://moevideo.net/video/00297.0036103fe3d513ef27915216fd29',
-            'md5': '129f5ae1f6585d0e9bb4f38e774ffb3a',
-            'info_dict': {
-                'id': '00297.0036103fe3d513ef27915216fd29',
-                'ext': 'flv',
-                'title': 'Sink cut out machine',
-                'description': 'md5:f29ff97b663aefa760bf7ca63c8ca8a8',
-                'thumbnail': r're:^https?://.*\.jpg$',
-                'width': 540,
-                'height': 360,
-                'duration': 179,
-                'filesize': 17822500,
-            },
-            'skip': 'Video has been removed',
-        },
-        {
-            'url': 'http://playreplay.net/video/77107.7f325710a627383d40540d8e991a',
-            'md5': '74f0a014d5b661f0f0e2361300d1620e',
-            'info_dict': {
-                'id': '77107.7f325710a627383d40540d8e991a',
-                'ext': 'flv',
-                'title': 'Operacion Condor.',
-                'description': 'md5:7e68cb2fcda66833d5081c542491a9a3',
-                'thumbnail': r're:^https?://.*\.jpg$',
-                'width': 480,
-                'height': 296,
-                'duration': 6027,
-                'filesize': 588257923,
-            },
-            'skip': 'Video has been removed',
-        },
-    ]
-
-    def _real_extract(self, url):
-        host, video_id = self._match_valid_url(url).groups()
-
-        webpage = self._download_webpage(
-            'http://%s/video/%s' % (host, video_id),
-            video_id, 'Downloading webpage')
-
-        title = self._og_search_title(webpage)
-
-        embed_webpage = self._download_webpage(
-            'http://%s/embed/%s' % (host, video_id),
-            video_id, 'Downloading embed webpage')
-        video = self._parse_json(self._search_regex(
-            r'mvplayer\("#player"\s*,\s*({.+})',
-            embed_webpage, 'mvplayer'), video_id)['video']
-
-        return {
-            'id': video_id,
-            'title': title,
-            'thumbnail': video.get('poster') or self._og_search_thumbnail(webpage),
-            'description': clean_html(self._og_search_description(webpage)),
-            'duration': int_or_none(self._og_search_property('video:duration', webpage)),
-            'url': video['ourUrl'],
-        }
diff --git a/yt_dlp/extractor/mofosex.py b/yt_dlp/extractor/mofosex.py
deleted file mode 100644 (file)
index 9cb6980..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    int_or_none,
-    str_to_int,
-    unified_strdate,
-)
-from .keezmovies import KeezMoviesIE
-
-
-class MofosexIE(KeezMoviesIE):  # XXX: Do not subclass from concrete IE
-    _VALID_URL = r'https?://(?:www\.)?mofosex\.com/videos/(?P<id>\d+)/(?P<display_id>[^/?#&.]+)\.html'
-    _TESTS = [{
-        'url': 'http://www.mofosex.com/videos/318131/amateur-teen-playing-and-masturbating-318131.html',
-        'md5': '558fcdafbb63a87c019218d6e49daf8a',
-        'info_dict': {
-            'id': '318131',
-            'display_id': 'amateur-teen-playing-and-masturbating-318131',
-            'ext': 'mp4',
-            'title': 'amateur teen playing and masturbating',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'upload_date': '20121114',
-            'view_count': int,
-            'like_count': int,
-            'dislike_count': int,
-            'age_limit': 18,
-        }
-    }, {
-        # This video is no longer available
-        'url': 'http://www.mofosex.com/videos/5018/japanese-teen-music-video.html',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        webpage, info = self._extract_info(url)
-
-        view_count = str_to_int(self._search_regex(
-            r'VIEWS:</span>\s*([\d,.]+)', webpage, 'view count', fatal=False))
-        like_count = int_or_none(self._search_regex(
-            r'id=["\']amountLikes["\'][^>]*>(\d+)', webpage,
-            'like count', fatal=False))
-        dislike_count = int_or_none(self._search_regex(
-            r'id=["\']amountDislikes["\'][^>]*>(\d+)', webpage,
-            'like count', fatal=False))
-        upload_date = unified_strdate(self._html_search_regex(
-            r'Added:</span>([^<]+)', webpage, 'upload date', fatal=False))
-
-        info.update({
-            'view_count': view_count,
-            'like_count': like_count,
-            'dislike_count': dislike_count,
-            'upload_date': upload_date,
-            'thumbnail': self._og_search_thumbnail(webpage),
-        })
-
-        return info
-
-
-class MofosexEmbedIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?mofosex\.com/embed/?\?.*?\bvideoid=(?P<id>\d+)'
-    _EMBED_REGEX = [r'<iframe[^>]+\bsrc=["\'](?P<url>(?:https?:)?//(?:www\.)?mofosex\.com/embed/?\?.*?\bvideoid=\d+)']
-    _TESTS = [{
-        'url': 'https://www.mofosex.com/embed/?videoid=318131&referrer=KM',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        return self.url_result(
-            'http://www.mofosex.com/videos/{0}/{0}.html'.format(video_id),
-            ie=MofosexIE.ie_key(), video_id=video_id)
diff --git a/yt_dlp/extractor/movieclips.py b/yt_dlp/extractor/movieclips.py
deleted file mode 100644 (file)
index f7f2921..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    smuggle_url,
-    float_or_none,
-    parse_iso8601,
-    update_url_query,
-)
-
-
-class MovieClipsIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?movieclips\.com/videos/.+-(?P<id>\d+)(?:\?|$)'
-    _TEST = {
-        'url': 'http://www.movieclips.com/videos/warcraft-trailer-1-561180739597',
-        'md5': '42b5a0352d4933a7bd54f2104f481244',
-        'info_dict': {
-            'id': 'pKIGmG83AqD9',
-            'ext': 'mp4',
-            'title': 'Warcraft Trailer 1',
-            'description': 'Watch Trailer 1 from Warcraft (2016). Legendary’s WARCRAFT is a 3D epic adventure of world-colliding conflict based.',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'timestamp': 1446843055,
-            'upload_date': '20151106',
-            'uploader': 'Movieclips',
-        },
-        'add_ie': ['ThePlatform'],
-        'skip': 'redirects to YouTube',
-    }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-        video = next(v for v in self._parse_json(self._search_regex(
-            r'var\s+__REACT_ENGINE__\s*=\s*({.+});',
-            webpage, 'react engine'), video_id)['playlist']['videos'] if v['id'] == video_id)
-
-        return {
-            '_type': 'url_transparent',
-            'ie_key': 'ThePlatform',
-            'url': smuggle_url(update_url_query(
-                video['contentUrl'], {'mbr': 'true'}), {'force_smil_url': True}),
-            'title': self._og_search_title(webpage),
-            'description': self._html_search_meta('description', webpage),
-            'duration': float_or_none(video.get('duration')),
-            'timestamp': parse_iso8601(video.get('dateCreated')),
-            'thumbnail': video.get('defaultImage'),
-            'uploader': video.get('provider'),
-        }
index f91c53eba1d18b8319dffee5802e2688a8a9739b..77d1806a3a43ce8f8989012ec9533e1a812b06e9 100644 (file)
@@ -11,6 +11,7 @@
 
 
 class MSNIE(InfoExtractor):
 
 
 class MSNIE(InfoExtractor):
+    _WORKING = False
     _VALID_URL = r'https?://(?:(?:www|preview)\.)?msn\.com/(?:[^/]+/)+(?P<display_id>[^/]+)/[a-z]{2}-(?P<id>[\da-zA-Z]+)'
     _TESTS = [{
         'url': 'https://www.msn.com/en-in/money/video/7-ways-to-get-rid-of-chest-congestion/vi-BBPxU6d',
     _VALID_URL = r'https?://(?:(?:www|preview)\.)?msn\.com/(?:[^/]+/)+(?P<display_id>[^/]+)/[a-z]{2}-(?P<id>[\da-zA-Z]+)'
     _TESTS = [{
         'url': 'https://www.msn.com/en-in/money/video/7-ways-to-get-rid-of-chest-congestion/vi-BBPxU6d',
diff --git a/yt_dlp/extractor/mwave.py b/yt_dlp/extractor/mwave.py
deleted file mode 100644 (file)
index efbfd9d..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-from .common import InfoExtractor
-from ..compat import compat_str
-from ..utils import (
-    int_or_none,
-    parse_duration,
-)
-
-
-class MwaveIE(InfoExtractor):
-    _VALID_URL = r'https?://mwave\.interest\.me/(?:[^/]+/)?mnettv/videodetail\.m\?searchVideoDetailVO\.clip_id=(?P<id>[0-9]+)'
-    _URL_TEMPLATE = 'http://mwave.interest.me/mnettv/videodetail.m?searchVideoDetailVO.clip_id=%s'
-    _TESTS = [{
-        'url': 'http://mwave.interest.me/mnettv/videodetail.m?searchVideoDetailVO.clip_id=168859',
-        # md5 is unstable
-        'info_dict': {
-            'id': '168859',
-            'ext': 'flv',
-            'title': '[M COUNTDOWN] SISTAR - SHAKE IT',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'uploader': 'M COUNTDOWN',
-            'duration': 206,
-            'view_count': int,
-        }
-    }, {
-        'url': 'http://mwave.interest.me/en/mnettv/videodetail.m?searchVideoDetailVO.clip_id=176199',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        vod_info = self._download_json(
-            'http://mwave.interest.me/onair/vod_info.m?vodtype=CL&sectorid=&endinfo=Y&id=%s' % video_id,
-            video_id, 'Download vod JSON')
-
-        formats = []
-        for num, cdn_info in enumerate(vod_info['cdn']):
-            stream_url = cdn_info.get('url')
-            if not stream_url:
-                continue
-            stream_name = cdn_info.get('name') or compat_str(num)
-            f4m_stream = self._download_json(
-                stream_url, video_id,
-                'Download %s stream JSON' % stream_name)
-            f4m_url = f4m_stream.get('fileurl')
-            if not f4m_url:
-                continue
-            formats.extend(
-                self._extract_f4m_formats(f4m_url + '&hdcore=3.0.3', video_id, f4m_id=stream_name))
-
-        return {
-            'id': video_id,
-            'title': vod_info['title'],
-            'thumbnail': vod_info.get('cover'),
-            'uploader': vod_info.get('program_title'),
-            'duration': parse_duration(vod_info.get('time')),
-            'view_count': int_or_none(vod_info.get('hit')),
-            'formats': formats,
-        }
-
-
-class MwaveMeetGreetIE(InfoExtractor):
-    _VALID_URL = r'https?://mwave\.interest\.me/(?:[^/]+/)?meetgreet/view/(?P<id>\d+)'
-    _TESTS = [{
-        'url': 'http://mwave.interest.me/meetgreet/view/256',
-        'info_dict': {
-            'id': '173294',
-            'ext': 'flv',
-            'title': '[MEET&GREET] Park BoRam',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'uploader': 'Mwave',
-            'duration': 3634,
-            'view_count': int,
-        }
-    }, {
-        'url': 'http://mwave.interest.me/en/meetgreet/view/256',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-        clip_id = self._html_search_regex(
-            r'<iframe[^>]+src="/mnettv/ifr_clip\.m\?searchVideoDetailVO\.clip_id=(\d+)',
-            webpage, 'clip ID')
-        clip_url = MwaveIE._URL_TEMPLATE % clip_id
-        return self.url_result(clip_url, 'Mwave', clip_id)
diff --git a/yt_dlp/extractor/mychannels.py b/yt_dlp/extractor/mychannels.py
deleted file mode 100644 (file)
index 8a70c1f..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-from .common import InfoExtractor
-
-
-class MyChannelsIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?mychannels\.com/.*(?P<id_type>video|production)_id=(?P<id>[0-9]+)'
-    _TEST = {
-        'url': 'https://mychannels.com/missholland/miss-holland?production_id=3416',
-        'md5': 'b8993daad4262dd68d89d651c0c52c45',
-        'info_dict': {
-            'id': 'wUUDZZep6vQD',
-            'ext': 'mp4',
-            'title': 'Miss Holland joins VOTE LEAVE',
-            'description': 'Miss Holland | #13 Not a potato',
-            'uploader': 'Miss Holland',
-        }
-    }
-
-    def _real_extract(self, url):
-        id_type, url_id = self._match_valid_url(url).groups()
-        webpage = self._download_webpage(url, url_id)
-        video_data = self._html_search_regex(r'<div([^>]+data-%s-id="%s"[^>]+)>' % (id_type, url_id), webpage, 'video data')
-
-        def extract_data_val(attr, fatal=False):
-            return self._html_search_regex(r'data-%s\s*=\s*"([^"]+)"' % attr, video_data, attr, fatal=fatal)
-        minoto_id = extract_data_val('minoto-id') or self._search_regex(r'/id/([a-zA-Z0-9]+)', extract_data_val('video-src', True), 'minoto id')
-
-        return {
-            '_type': 'url_transparent',
-            'url': 'minoto:%s' % minoto_id,
-            'id': url_id,
-            'title': extract_data_val('title', True),
-            'description': extract_data_val('description'),
-            'thumbnail': extract_data_val('image'),
-            'uploader': extract_data_val('channel'),
-        }
diff --git a/yt_dlp/extractor/myvi.py b/yt_dlp/extractor/myvi.py
deleted file mode 100644 (file)
index df7200b..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-from .common import InfoExtractor
-from .vimple import SprutoBaseIE
-
-
-class MyviIE(SprutoBaseIE):
-    _VALID_URL = r'''(?x)
-                        (?:
-                            https?://
-                                (?:www\.)?
-                                myvi\.
-                                (?:
-                                    (?:ru/player|tv)/
-                                    (?:
-                                        (?:
-                                            embed/html|
-                                            flash|
-                                            api/Video/Get
-                                        )/|
-                                        content/preloader\.swf\?.*\bid=
-                                    )|
-                                    ru/watch/
-                                )|
-                            myvi:
-                        )
-                        (?P<id>[\da-zA-Z_-]+)
-                    '''
-    _EMBED_REGEX = [r'<iframe[^>]+?src=(["\'])(?P<url>(?:https?:)?//myvi\.(?:ru/player|tv)/(?:embed/html|flash)/[^"]+)\1']
-    _TESTS = [{
-        'url': 'http://myvi.ru/player/embed/html/oOy4euHA6LVwNNAjhD9_Jq5Ha2Qf0rtVMVFMAZav8wObeRTZaCATzucDQIDph8hQU0',
-        'md5': '571bbdfba9f9ed229dc6d34cc0f335bf',
-        'info_dict': {
-            'id': 'f16b2bbd-cde8-481c-a981-7cd48605df43',
-            'ext': 'mp4',
-            'title': 'хозяин жизни',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'duration': 25,
-        },
-    }, {
-        'url': 'http://myvi.ru/player/content/preloader.swf?id=oOy4euHA6LVwNNAjhD9_Jq5Ha2Qf0rtVMVFMAZav8wOYf1WFpPfc_bWTKGVf_Zafr0',
-        'only_matching': True,
-    }, {
-        'url': 'http://myvi.ru/player/api/Video/Get/oOy4euHA6LVwNNAjhD9_Jq5Ha2Qf0rtVMVFMAZav8wObeRTZaCATzucDQIDph8hQU0',
-        'only_matching': True,
-    }, {
-        'url': 'http://myvi.tv/embed/html/oTGTNWdyz4Zwy_u1nraolwZ1odenTd9WkTnRfIL9y8VOgHYqOHApE575x4_xxS9Vn0?ap=0',
-        'only_matching': True,
-    }, {
-        'url': 'http://myvi.ru/player/flash/ocp2qZrHI-eZnHKQBK4cZV60hslH8LALnk0uBfKsB-Q4WnY26SeGoYPi8HWHxu0O30',
-        'only_matching': True,
-    }, {
-        'url': 'https://www.myvi.ru/watch/YwbqszQynUaHPn_s82sx0Q2',
-        'only_matching': True,
-    }, {
-        'url': 'myvi:YwbqszQynUaHPn_s82sx0Q2',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        spruto = self._download_json(
-            'http://myvi.ru/player/api/Video/Get/%s?sig' % video_id, video_id)['sprutoData']
-
-        return self._extract_spruto(spruto, video_id)
-
-
-class MyviEmbedIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?myvi\.tv/(?:[^?]+\?.*?\bv=|embed/)(?P<id>[\da-z]+)'
-    _TESTS = [{
-        'url': 'https://www.myvi.tv/embed/ccdqic3wgkqwpb36x9sxg43t4r',
-        'info_dict': {
-            'id': 'b3ea0663-3234-469d-873e-7fecf36b31d1',
-            'ext': 'mp4',
-            'title': 'Твоя (original song).mp4',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'duration': 277,
-        },
-        'params': {
-            'skip_download': True,
-        },
-    }, {
-        'url': 'https://www.myvi.tv/idmi6o?v=ccdqic3wgkqwpb36x9sxg43t4r#watch',
-        'only_matching': True,
-    }]
-
-    @classmethod
-    def suitable(cls, url):
-        return False if MyviIE.suitable(url) else super(MyviEmbedIE, cls).suitable(url)
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        webpage = self._download_webpage(
-            'https://www.myvi.tv/embed/%s' % video_id, video_id)
-
-        myvi_id = self._search_regex(
-            r'CreatePlayer\s*\(\s*["\'].*?\bv=([\da-zA-Z_]+)',
-            webpage, 'video id')
-
-        return self.url_result('myvi:%s' % myvi_id, ie=MyviIE.ie_key())
diff --git a/yt_dlp/extractor/newstube.py b/yt_dlp/extractor/newstube.py
deleted file mode 100644 (file)
index 820eb4b..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-import base64
-import hashlib
-
-from .common import InfoExtractor
-from ..aes import aes_cbc_decrypt_bytes, unpad_pkcs7
-from ..utils import (
-    int_or_none,
-    parse_codecs,
-    parse_duration,
-)
-
-
-class NewstubeIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?newstube\.ru/media/(?P<id>.+)'
-    _TEST = {
-        'url': 'http://www.newstube.ru/media/telekanal-cnn-peremestil-gorod-slavyansk-v-krym',
-        'md5': '9d10320ad473444352f72f746ccb8b8c',
-        'info_dict': {
-            'id': '728e0ef2-e187-4012-bac0-5a081fdcb1f6',
-            'ext': 'mp4',
-            'title': 'Телеканал CNN переместил город Славянск в Крым',
-            'description': 'md5:419a8c9f03442bc0b0a794d689360335',
-            'duration': 31.05,
-        },
-    }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        page = self._download_webpage(url, video_id)
-        title = self._html_search_meta(['og:title', 'twitter:title'], page, fatal=True)
-
-        video_guid = self._html_search_regex(
-            r'<meta\s+property="og:video(?::(?:(?:secure_)?url|iframe))?"\s+content="https?://(?:www\.)?newstube\.ru/embed/(?P<guid>[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12})',
-            page, 'video GUID')
-
-        enc_data = base64.b64decode(self._download_webpage(
-            'https://www.newstube.ru/embed/api/player/getsources2',
-            video_guid, query={
-                'guid': video_guid,
-                'ff': 3,
-            }))
-        key = hashlib.pbkdf2_hmac(
-            'sha1', video_guid.replace('-', '').encode(), enc_data[:16], 1)[:16]
-        dec_data = unpad_pkcs7(aes_cbc_decrypt_bytes(enc_data[32:], key, enc_data[16:32]))
-        sources = self._parse_json(dec_data, video_guid)
-
-        formats = []
-        for source in sources:
-            source_url = source.get('Src')
-            if not source_url:
-                continue
-            height = int_or_none(source.get('Height'))
-            f = {
-                'format_id': 'http' + ('-%dp' % height if height else ''),
-                'url': source_url,
-                'width': int_or_none(source.get('Width')),
-                'height': height,
-            }
-            source_type = source.get('Type')
-            if source_type:
-                f.update(parse_codecs(self._search_regex(
-                    r'codecs="([^"]+)"', source_type, 'codecs', fatal=False)))
-            formats.append(f)
-
-        self._check_formats(formats, video_guid)
-
-        return {
-            'id': video_guid,
-            'title': title,
-            'description': self._html_search_meta(['description', 'og:description'], page),
-            'thumbnail': self._html_search_meta(['og:image:secure_url', 'og:image', 'twitter:image'], page),
-            'duration': parse_duration(self._html_search_meta('duration', page)),
-            'formats': formats,
-        }
index de22cb8d6428a28214940c5f23a79c46c1eb7439..165d8ce9d22c479dc515f64a8f989eb479fc8172 100644 (file)
@@ -188,26 +188,6 @@ def _get_feed_url(self, uri, url=None):
         return self._remove_template_parameter(config['feedWithQueryParams'])
 
 
         return self._remove_template_parameter(config['feedWithQueryParams'])
 
 
-class NickNightIE(NickDeIE):  # XXX: Do not subclass from concrete IE
-    IE_NAME = 'nicknight'
-    _VALID_URL = r'https?://(?:www\.)(?P<host>nicknight\.(?:de|at|tv))/(?:playlist|shows)/(?:[^/]+/)*(?P<id>[^/?#&]+)'
-    _TESTS = [{
-        'url': 'http://www.nicknight.at/shows/977-awkward/videos/85987-nimmer-beste-freunde',
-        'only_matching': True,
-    }, {
-        'url': 'http://www.nicknight.at/shows/977-awkward',
-        'only_matching': True,
-    }, {
-        'url': 'http://www.nicknight.at/shows/1900-faking-it',
-        'only_matching': True,
-    }]
-
-    def _extract_mrss_url(self, webpage, *args):
-        return self._search_regex(
-            r'mrss\s*:\s*(["\'])(?P<url>http.+?)\1', webpage,
-            'mrss url', group='url')
-
-
 class NickRuIE(MTVServicesInfoExtractor):
     IE_NAME = 'nickelodeonru'
     _VALID_URL = r'https?://(?:www\.)nickelodeon\.(?:ru|fr|es|pt|ro|hu|com\.tr)/[^/]+/(?:[^/]+/)*(?P<id>[^/?#&]+)'
 class NickRuIE(MTVServicesInfoExtractor):
     IE_NAME = 'nickelodeonru'
     _VALID_URL = r'https?://(?:www\.)nickelodeon\.(?:ru|fr|es|pt|ro|hu|com\.tr)/[^/]+/(?:[^/]+/)*(?P<id>[^/?#&]+)'
diff --git a/yt_dlp/extractor/normalboots.py b/yt_dlp/extractor/normalboots.py
deleted file mode 100644 (file)
index 07babcd..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-from .common import InfoExtractor
-from .jwplatform import JWPlatformIE
-
-from ..utils import (
-    unified_strdate,
-)
-
-
-class NormalbootsIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?normalboots\.com/video/(?P<id>[0-9a-z-]*)/?$'
-    _TEST = {
-        'url': 'http://normalboots.com/video/home-alone-games-jontron/',
-        'info_dict': {
-            'id': 'home-alone-games-jontron',
-            'ext': 'mp4',
-            'title': 'Home Alone Games - JonTron - NormalBoots',
-            'description': 'Jon is late for Christmas. Typical. Thanks to: Paul Ritchey for Co-Writing/Filming: http://www.youtube.com/user/ContinueShow Michael Azzi for Christmas Intro Animation: http://michafrar.tumblr.com/ Jerrod Waters for Christmas Intro Music: http://www.youtube.com/user/xXJerryTerryXx Casey Ormond for ‘Tense Battle Theme’:\xa0http://www.youtube.com/Kiamet/',
-            'uploader': 'JonTron',
-            'upload_date': '20140125',
-        },
-        'params': {
-            # m3u8 download
-            'skip_download': True,
-        },
-        'add_ie': ['JWPlatform'],
-    }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-
-        video_uploader = self._html_search_regex(
-            r'Posted\sby\s<a\shref="[A-Za-z0-9/]*">(?P<uploader>[A-Za-z]*)\s</a>',
-            webpage, 'uploader', fatal=False)
-        video_upload_date = unified_strdate(self._html_search_regex(
-            r'<span style="text-transform:uppercase; font-size:inherit;">[A-Za-z]+, (?P<date>.*)</span>',
-            webpage, 'date', fatal=False))
-
-        jwplatform_url = JWPlatformIE._extract_url(webpage)
-
-        return {
-            '_type': 'url_transparent',
-            'id': video_id,
-            'url': jwplatform_url,
-            'ie_key': JWPlatformIE.ie_key(),
-            'title': self._og_search_title(webpage),
-            'description': self._og_search_description(webpage),
-            'thumbnail': self._og_search_thumbnail(webpage),
-            'uploader': video_uploader,
-            'upload_date': video_upload_date,
-        }
diff --git a/yt_dlp/extractor/nosvideo.py b/yt_dlp/extractor/nosvideo.py
deleted file mode 100644 (file)
index 7e9688c..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..networking import Request
-from ..utils import (
-    ExtractorError,
-    urlencode_postdata,
-    xpath_text,
-    xpath_with_ns,
-)
-
-_x = lambda p: xpath_with_ns(p, {'xspf': 'http://xspf.org/ns/0/'})
-
-
-class NosVideoIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?nosvideo\.com/' + \
-                 r'(?:embed/|\?v=)(?P<id>[A-Za-z0-9]{12})/?'
-    _PLAYLIST_URL = 'http://nosvideo.com/xml/{xml_id:s}.xml'
-    _FILE_DELETED_REGEX = r'<b>File Not Found</b>'
-    _TEST = {
-        'url': 'http://nosvideo.com/?v=mu8fle7g7rpq',
-        'md5': '6124ed47130d8be3eacae635b071e6b6',
-        'info_dict': {
-            'id': 'mu8fle7g7rpq',
-            'ext': 'mp4',
-            'title': 'big_buck_bunny_480p_surround-fix.avi.mp4',
-            'thumbnail': r're:^https?://.*\.jpg$',
-        }
-    }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        fields = {
-            'id': video_id,
-            'op': 'download1',
-            'method_free': 'Continue to Video',
-        }
-        req = Request(url, urlencode_postdata(fields))
-        req.headers['Content-type'] = 'application/x-www-form-urlencoded'
-        webpage = self._download_webpage(req, video_id,
-                                         'Downloading download page')
-        if re.search(self._FILE_DELETED_REGEX, webpage) is not None:
-            raise ExtractorError('Video %s does not exist' % video_id,
-                                 expected=True)
-
-        xml_id = self._search_regex(r'php\|([^\|]+)\|', webpage, 'XML ID')
-        playlist_url = self._PLAYLIST_URL.format(xml_id=xml_id)
-        playlist = self._download_xml(playlist_url, video_id)
-
-        track = playlist.find(_x('.//xspf:track'))
-        if track is None:
-            raise ExtractorError(
-                'XML playlist is missing the \'track\' element',
-                expected=True)
-        title = xpath_text(track, _x('./xspf:title'), 'title')
-        url = xpath_text(track, _x('./xspf:file'), 'URL', fatal=True)
-        thumbnail = xpath_text(track, _x('./xspf:image'), 'thumbnail')
-        if title is not None:
-            title = title.strip()
-
-        formats = [{
-            'format_id': 'sd',
-            'url': url,
-        }]
-
-        return {
-            'id': video_id,
-            'title': title,
-            'thumbnail': thumbnail,
-            'formats': formats,
-        }
index 798d03417b51bb39597f0225b0e4920ec6e62263..1e8cf0b754213f81fe218c2e1679efd2a3d318cc 100644 (file)
@@ -2,6 +2,7 @@
 
 
 class NRLTVIE(InfoExtractor):
 
 
 class NRLTVIE(InfoExtractor):
+    _WORKING = False
     _VALID_URL = r'https?://(?:www\.)?nrl\.com/tv(/[^/]+)*/(?P<id>[^/?&#]+)'
     _TEST = {
         'url': 'https://www.nrl.com/tv/news/match-highlights-titans-v-knights-862805/',
     _VALID_URL = r'https?://(?:www\.)?nrl\.com/tv(/[^/]+)*/(?P<id>[^/?&#]+)'
     _TEST = {
         'url': 'https://www.nrl.com/tv/news/match-highlights-titans-v-knights-862805/',
diff --git a/yt_dlp/extractor/ooyala.py b/yt_dlp/extractor/ooyala.py
deleted file mode 100644 (file)
index 65afccd..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-import base64
-import re
-
-from .common import InfoExtractor
-from ..compat import (
-    compat_b64decode,
-    compat_str,
-)
-from ..utils import (
-    determine_ext,
-    float_or_none,
-    int_or_none,
-    smuggle_url,
-    try_get,
-    unsmuggle_url,
-)
-
-
-class OoyalaBaseIE(InfoExtractor):
-    _PLAYER_BASE = 'http://player.ooyala.com/'
-    _CONTENT_TREE_BASE = _PLAYER_BASE + 'player_api/v1/content_tree/'
-    _AUTHORIZATION_URL_TEMPLATE = _PLAYER_BASE + 'sas/player_api/v2/authorization/embed_code/%s/%s'
-
-    def _extract(self, content_tree_url, video_id, domain=None, supportedformats=None, embed_token=None):
-        content_tree = self._download_json(content_tree_url, video_id)['content_tree']
-        metadata = content_tree[list(content_tree)[0]]
-        embed_code = metadata['embed_code']
-        pcode = metadata.get('asset_pcode') or embed_code
-        title = metadata['title']
-
-        auth_data = self._download_json(
-            self._AUTHORIZATION_URL_TEMPLATE % (pcode, embed_code),
-            video_id, headers=self.geo_verification_headers(), query={
-                'domain': domain or 'player.ooyala.com',
-                'supportedFormats': supportedformats or 'mp4,rtmp,m3u8,hds,dash,smooth',
-                'embedToken': embed_token,
-            })['authorization_data'][embed_code]
-
-        urls = []
-        formats = []
-        streams = auth_data.get('streams') or [{
-            'delivery_type': 'hls',
-            'url': {
-                'data': base64.b64encode(('http://player.ooyala.com/hls/player/all/%s.m3u8' % embed_code).encode()).decode(),
-            }
-        }]
-        for stream in streams:
-            url_data = try_get(stream, lambda x: x['url']['data'], compat_str)
-            if not url_data:
-                continue
-            s_url = compat_b64decode(url_data).decode('utf-8')
-            if not s_url or s_url in urls:
-                continue
-            urls.append(s_url)
-            ext = determine_ext(s_url, None)
-            delivery_type = stream.get('delivery_type')
-            if delivery_type == 'hls' or ext == 'm3u8':
-                formats.extend(self._extract_m3u8_formats(
-                    re.sub(r'/ip(?:ad|hone)/', '/all/', s_url), embed_code, 'mp4', 'm3u8_native',
-                    m3u8_id='hls', fatal=False))
-            elif delivery_type == 'hds' or ext == 'f4m':
-                formats.extend(self._extract_f4m_formats(
-                    s_url + '?hdcore=3.7.0', embed_code, f4m_id='hds', fatal=False))
-            elif delivery_type == 'dash' or ext == 'mpd':
-                formats.extend(self._extract_mpd_formats(
-                    s_url, embed_code, mpd_id='dash', fatal=False))
-            elif delivery_type == 'smooth':
-                self._extract_ism_formats(
-                    s_url, embed_code, ism_id='mss', fatal=False)
-            elif ext == 'smil':
-                formats.extend(self._extract_smil_formats(
-                    s_url, embed_code, fatal=False))
-            else:
-                formats.append({
-                    'url': s_url,
-                    'ext': ext or delivery_type,
-                    'vcodec': stream.get('video_codec'),
-                    'format_id': delivery_type,
-                    'width': int_or_none(stream.get('width')),
-                    'height': int_or_none(stream.get('height')),
-                    'abr': int_or_none(stream.get('audio_bitrate')),
-                    'vbr': int_or_none(stream.get('video_bitrate')),
-                    'fps': float_or_none(stream.get('framerate')),
-                })
-        if not formats and not auth_data.get('authorized'):
-            self.raise_no_formats('%s said: %s' % (
-                self.IE_NAME, auth_data['message']), expected=True)
-
-        subtitles = {}
-        for lang, sub in metadata.get('closed_captions_vtt', {}).get('captions', {}).items():
-            sub_url = sub.get('url')
-            if not sub_url:
-                continue
-            subtitles[lang] = [{
-                'url': sub_url,
-            }]
-
-        return {
-            'id': embed_code,
-            'title': title,
-            'description': metadata.get('description'),
-            'thumbnail': metadata.get('thumbnail_image') or metadata.get('promo_image'),
-            'duration': float_or_none(metadata.get('duration'), 1000),
-            'subtitles': subtitles,
-            'formats': formats,
-        }
-
-
-class OoyalaIE(OoyalaBaseIE):
-    _VALID_URL = r'(?:ooyala:|https?://.+?\.ooyala\.com/.*?(?:embedCode|ec)=)(?P<id>.+?)(&|$)'
-
-    _TESTS = [
-        {
-            # From http://it.slashdot.org/story/13/04/25/178216/recovering-data-from-broken-hard-drives-and-ssds-video
-            'url': 'http://player.ooyala.com/player.js?embedCode=pxczE2YjpfHfn1f3M-ykG_AmJRRn0PD8',
-            'info_dict': {
-                'id': 'pxczE2YjpfHfn1f3M-ykG_AmJRRn0PD8',
-                'ext': 'mp4',
-                'title': 'Explaining Data Recovery from Hard Drives and SSDs',
-                'description': 'How badly damaged does a drive have to be to defeat Russell and his crew? Apparently, smashed to bits.',
-                'duration': 853.386,
-            },
-            # The video in the original webpage now uses PlayWire
-            'skip': 'Ooyala said: movie expired',
-        }, {
-            # Only available for ipad
-            'url': 'http://player.ooyala.com/player.js?embedCode=x1b3lqZDq9y_7kMyC2Op5qo-p077tXD0',
-            'info_dict': {
-                'id': 'x1b3lqZDq9y_7kMyC2Op5qo-p077tXD0',
-                'ext': 'mp4',
-                'title': 'Simulation Overview - Levels of Simulation',
-                'duration': 194.948,
-            },
-        },
-        {
-            # Information available only through SAS api
-            # From http://community.plm.automation.siemens.com/t5/News-NX-Manufacturing/Tool-Path-Divide/ba-p/4187
-            'url': 'http://player.ooyala.com/player.js?embedCode=FiOG81ZTrvckcchQxmalf4aQj590qTEx',
-            'md5': 'a84001441b35ea492bc03736e59e7935',
-            'info_dict': {
-                'id': 'FiOG81ZTrvckcchQxmalf4aQj590qTEx',
-                'ext': 'mp4',
-                'title': 'Divide Tool Path.mp4',
-                'duration': 204.405,
-            }
-        },
-        {
-            # empty stream['url']['data']
-            'url': 'http://player.ooyala.com/player.js?embedCode=w2bnZtYjE6axZ_dw1Cd0hQtXd_ige2Is',
-            'only_matching': True,
-        }
-    ]
-
-    def _extract_from_webpage(self, url, webpage):
-        mobj = (re.search(r'player\.ooyala\.com/[^"?]+[?#][^"]*?(?:embedCode|ec)=(?P<ec>[^"&]+)', webpage)
-                or re.search(r'OO\.Player\.create\([\'"].*?[\'"],\s*[\'"](?P<ec>.{32})[\'"]', webpage)
-                or re.search(r'OO\.Player\.create\.apply\(\s*OO\.Player\s*,\s*op\(\s*\[\s*[\'"][^\'"]*[\'"]\s*,\s*[\'"](?P<ec>.{32})[\'"]', webpage)
-                or re.search(r'SBN\.VideoLinkset\.ooyala\([\'"](?P<ec>.{32})[\'"]\)', webpage)
-                or re.search(r'data-ooyala-video-id\s*=\s*[\'"](?P<ec>.{32})[\'"]', webpage))
-        if mobj is not None:
-            embed_token = self._search_regex(
-                r'embedToken[\'"]?\s*:\s*[\'"]([^\'"]+)',
-                webpage, 'ooyala embed token', default=None)
-            yield self._build_url_result(smuggle_url(
-                mobj.group('ec'), {
-                    'domain': url,
-                    'embed_token': embed_token,
-                }))
-            return
-
-        # Look for multiple Ooyala embeds on SBN network websites
-        mobj = re.search(r'SBN\.VideoLinkset\.entryGroup\((\[.*?\])', webpage)
-        if mobj is not None:
-            for v in self._parse_json(mobj.group(1), self._generic_id(url), fatal=False) or []:
-                yield self._build_url_result(smuggle_url(v['provider_video_id'], {'domain': url}))
-
-    @staticmethod
-    def _url_for_embed_code(embed_code):
-        return 'http://player.ooyala.com/player.js?embedCode=%s' % embed_code
-
-    @classmethod
-    def _build_url_result(cls, embed_code):
-        return cls.url_result(cls._url_for_embed_code(embed_code),
-                              ie=cls.ie_key())
-
-    def _real_extract(self, url):
-        url, smuggled_data = unsmuggle_url(url, {})
-        embed_code = self._match_id(url)
-        domain = smuggled_data.get('domain')
-        supportedformats = smuggled_data.get('supportedformats')
-        embed_token = smuggled_data.get('embed_token')
-        content_tree_url = self._CONTENT_TREE_BASE + 'embed_code/%s/%s' % (embed_code, embed_code)
-        return self._extract(content_tree_url, embed_code, domain, supportedformats, embed_token)
-
-
-class OoyalaExternalIE(OoyalaBaseIE):
-    _VALID_URL = r'''(?x)
-                    (?:
-                        ooyalaexternal:|
-                        https?://.+?\.ooyala\.com/.*?\bexternalId=
-                    )
-                    (?P<partner_id>[^:]+)
-                    :
-                    (?P<id>.+)
-                    (?:
-                        :|
-                        .*?&pcode=
-                    )
-                    (?P<pcode>.+?)
-                    (?:&|$)
-                    '''
-
-    _TEST = {
-        'url': 'https://player.ooyala.com/player.js?externalId=espn:10365079&pcode=1kNG061cgaoolOncv54OAO1ceO-I&adSetCode=91cDU6NuXTGKz3OdjOxFdAgJVtQcKJnI&callback=handleEvents&hasModuleParams=1&height=968&playerBrandingId=7af3bd04449c444c964f347f11873075&targetReplaceId=videoPlayer&width=1656&wmode=opaque&allowScriptAccess=always',
-        'info_dict': {
-            'id': 'FkYWtmazr6Ed8xmvILvKLWjd4QvYZpzG',
-            'ext': 'mp4',
-            'title': 'dm_140128_30for30Shorts___JudgingJewellv2',
-            'duration': 1302.0,
-        },
-        'params': {
-            # m3u8 download
-            'skip_download': True,
-        },
-    }
-
-    def _real_extract(self, url):
-        partner_id, video_id, pcode = self._match_valid_url(url).groups()
-        content_tree_url = self._CONTENT_TREE_BASE + 'external_id/%s/%s:%s' % (pcode, partner_id, video_id)
-        return self._extract(content_tree_url, video_id)
diff --git a/yt_dlp/extractor/pandoratv.py b/yt_dlp/extractor/pandoratv.py
deleted file mode 100644 (file)
index ccc78da..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-from .common import InfoExtractor
-from ..compat import (
-    compat_str,
-)
-from ..utils import (
-    ExtractorError,
-    float_or_none,
-    parse_duration,
-    parse_qs,
-    str_to_int,
-    urlencode_postdata,
-)
-
-
-class PandoraTVIE(InfoExtractor):
-    IE_NAME = 'pandora.tv'
-    IE_DESC = '판도라TV'
-    _VALID_URL = r'''(?x)
-                        https?://
-                            (?:
-                                (?:www\.)?pandora\.tv/view/(?P<user_id>[^/]+)/(?P<id>\d+)|  # new format
-                                (?:.+?\.)?channel\.pandora\.tv/channel/video\.ptv\?|        # old format
-                                m\.pandora\.tv/?\?                                          # mobile
-                            )
-                    '''
-    _TESTS = [{
-        'url': 'http://jp.channel.pandora.tv/channel/video.ptv?c1=&prgid=53294230&ch_userid=mikakim&ref=main&lot=cate_01_2',
-        'info_dict': {
-            'id': '53294230',
-            'ext': 'flv',
-            'title': '頭を撫でてくれる?',
-            'description': '頭を撫でてくれる?',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'duration': 39,
-            'upload_date': '20151218',
-            'uploader': 'カワイイ動物まとめ',
-            'uploader_id': 'mikakim',
-            'view_count': int,
-            'like_count': int,
-        }
-    }, {
-        'url': 'http://channel.pandora.tv/channel/video.ptv?ch_userid=gogoucc&prgid=54721744',
-        'info_dict': {
-            'id': '54721744',
-            'ext': 'flv',
-            'title': '[HD] JAPAN COUNTDOWN 170423',
-            'description': '[HD] JAPAN COUNTDOWN 170423',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'duration': 1704.9,
-            'upload_date': '20170423',
-            'uploader': 'GOGO_UCC',
-            'uploader_id': 'gogoucc',
-            'view_count': int,
-            'like_count': int,
-        },
-        'params': {
-            # Test metadata only
-            'skip_download': True,
-        },
-    }, {
-        'url': 'http://www.pandora.tv/view/mikakim/53294230#36797454_new',
-        'only_matching': True,
-    }, {
-        'url': 'http://m.pandora.tv/?c=view&ch_userid=mikakim&prgid=54600346',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        mobj = self._match_valid_url(url)
-        user_id = mobj.group('user_id')
-        video_id = mobj.group('id')
-
-        if not user_id or not video_id:
-            qs = parse_qs(url)
-            video_id = qs.get('prgid', [None])[0]
-            user_id = qs.get('ch_userid', [None])[0]
-            if any(not f for f in (video_id, user_id,)):
-                raise ExtractorError('Invalid URL', expected=True)
-
-        data = self._download_json(
-            'http://m.pandora.tv/?c=view&m=viewJsonApi&ch_userid=%s&prgid=%s'
-            % (user_id, video_id), video_id)
-
-        info = data['data']['rows']['vod_play_info']['result']
-
-        formats = []
-        for format_id, format_url in info.items():
-            if not format_url:
-                continue
-            height = self._search_regex(
-                r'^v(\d+)[Uu]rl$', format_id, 'height', default=None)
-            if not height:
-                continue
-
-            play_url = self._download_json(
-                'http://m.pandora.tv/?c=api&m=play_url', video_id,
-                data=urlencode_postdata({
-                    'prgid': video_id,
-                    'runtime': info.get('runtime'),
-                    'vod_url': format_url,
-                }),
-                headers={
-                    'Origin': url,
-                    'Content-Type': 'application/x-www-form-urlencoded',
-                })
-            format_url = play_url.get('url')
-            if not format_url:
-                continue
-
-            formats.append({
-                'format_id': '%sp' % height,
-                'url': format_url,
-                'height': int(height),
-            })
-
-        return {
-            'id': video_id,
-            'title': info['subject'],
-            'description': info.get('body'),
-            'thumbnail': info.get('thumbnail') or info.get('poster'),
-            'duration': float_or_none(info.get('runtime'), 1000) or parse_duration(info.get('time')),
-            'upload_date': info['fid'].split('/')[-1][:8] if isinstance(info.get('fid'), compat_str) else None,
-            'uploader': info.get('nickname'),
-            'uploader_id': info.get('upload_userid'),
-            'view_count': str_to_int(info.get('hit')),
-            'like_count': str_to_int(info.get('likecnt')),
-            'formats': formats,
-        }
diff --git a/yt_dlp/extractor/people.py b/yt_dlp/extractor/people.py
deleted file mode 100644 (file)
index c5143c3..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-from .common import InfoExtractor
-
-
-class PeopleIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?people\.com/people/videos/0,,(?P<id>\d+),00\.html'
-
-    _TEST = {
-        'url': 'http://www.people.com/people/videos/0,,20995451,00.html',
-        'info_dict': {
-            'id': 'ref:20995451',
-            'ext': 'mp4',
-            'title': 'Astronaut Love Triangle Victim Speaks Out: “The Crime in 2007 Hasn’t Defined Us”',
-            'description': 'Colleen Shipman speaks to PEOPLE for the first time about life after the attack',
-            'thumbnail': r're:^https?://.*\.jpg',
-            'duration': 246.318,
-            'timestamp': 1458720585,
-            'upload_date': '20160323',
-            'uploader_id': '416418724',
-        },
-        'params': {
-            'skip_download': True,
-        },
-        'add_ie': ['BrightcoveNew'],
-    }
-
-    def _real_extract(self, url):
-        return self.url_result(
-            'http://players.brightcove.net/416418724/default_default/index.html?videoId=ref:%s'
-            % self._match_id(url), 'BrightcoveNew')
diff --git a/yt_dlp/extractor/playfm.py b/yt_dlp/extractor/playfm.py
deleted file mode 100644 (file)
index e895ba4..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-from .common import InfoExtractor
-from ..compat import compat_str
-from ..utils import (
-    ExtractorError,
-    int_or_none,
-    parse_iso8601,
-)
-
-
-class PlayFMIE(InfoExtractor):
-    IE_NAME = 'play.fm'
-    _VALID_URL = r'https?://(?:www\.)?play\.fm/(?P<slug>(?:[^/]+/)+(?P<id>[^/]+))/?(?:$|[?#])'
-
-    _TEST = {
-        'url': 'https://www.play.fm/dan-drastic/sven-tasnadi-leipzig-electronic-music-batofar-paris-fr-2014-07-12',
-        'md5': 'c505f8307825a245d0c7ad1850001f22',
-        'info_dict': {
-            'id': '71276',
-            'ext': 'mp3',
-            'title': 'Sven Tasnadi - LEIPZIG ELECTRONIC MUSIC @ Batofar (Paris,FR) - 2014-07-12',
-            'description': '',
-            'duration': 5627,
-            'timestamp': 1406033781,
-            'upload_date': '20140722',
-            'uploader': 'Dan Drastic',
-            'uploader_id': '71170',
-            'view_count': int,
-            'comment_count': int,
-        },
-    }
-
-    def _real_extract(self, url):
-        mobj = self._match_valid_url(url)
-        video_id = mobj.group('id')
-        slug = mobj.group('slug')
-
-        recordings = self._download_json(
-            'http://v2api.play.fm/recordings/slug/%s' % slug, video_id)
-
-        error = recordings.get('error')
-        if isinstance(error, dict):
-            raise ExtractorError(
-                '%s returned error: %s' % (self.IE_NAME, error.get('message')),
-                expected=True)
-
-        audio_url = recordings['audio']
-        video_id = compat_str(recordings.get('id') or video_id)
-        title = recordings['title']
-        description = recordings.get('description')
-        duration = int_or_none(recordings.get('recordingDuration'))
-        timestamp = parse_iso8601(recordings.get('created_at'))
-        uploader = recordings.get('page', {}).get('title')
-        uploader_id = compat_str(recordings.get('page', {}).get('id'))
-        view_count = int_or_none(recordings.get('playCount'))
-        comment_count = int_or_none(recordings.get('commentCount'))
-        categories = [tag['name'] for tag in recordings.get('tags', []) if tag.get('name')]
-
-        return {
-            'id': video_id,
-            'url': audio_url,
-            'title': title,
-            'description': description,
-            'duration': duration,
-            'timestamp': timestamp,
-            'uploader': uploader,
-            'uploader_id': uploader_id,
-            'view_count': view_count,
-            'comment_count': comment_count,
-            'categories': categories,
-        }
diff --git a/yt_dlp/extractor/plays.py b/yt_dlp/extractor/plays.py
deleted file mode 100644 (file)
index 9371f7b..0000000
+++ /dev/null
@@ -1,49 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..utils import int_or_none
-
-
-class PlaysTVIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?plays\.tv/(?:video|embeds)/(?P<id>[0-9a-f]{18})'
-    _TESTS = [{
-        'url': 'https://plays.tv/video/56af17f56c95335490/when-you-outplay-the-azir-wall',
-        'md5': 'dfeac1198506652b5257a62762cec7bc',
-        'info_dict': {
-            'id': '56af17f56c95335490',
-            'ext': 'mp4',
-            'title': 'Bjergsen - When you outplay the Azir wall',
-            'description': 'Posted by Bjergsen',
-        }
-    }, {
-        'url': 'https://plays.tv/embeds/56af17f56c95335490',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(
-            'https://plays.tv/video/%s' % video_id, video_id)
-
-        info = self._search_json_ld(webpage, video_id,)
-
-        mpd_url, sources = re.search(
-            r'(?s)<video[^>]+data-mpd="([^"]+)"[^>]*>(.+?)</video>',
-            webpage).groups()
-        formats = self._extract_mpd_formats(
-            self._proto_relative_url(mpd_url), video_id, mpd_id='DASH')
-        for format_id, height, format_url in re.findall(r'<source\s+res="((\d+)h?)"\s+src="([^"]+)"', sources):
-            formats.append({
-                'url': self._proto_relative_url(format_url),
-                'format_id': 'http-' + format_id,
-                'height': int_or_none(height),
-            })
-
-        info.update({
-            'id': video_id,
-            'description': self._og_search_description(webpage),
-            'thumbnail': info.get('thumbnail') or self._og_search_thumbnail(webpage),
-            'formats': formats,
-        })
-
-        return info
diff --git a/yt_dlp/extractor/playvid.py b/yt_dlp/extractor/playvid.py
deleted file mode 100644 (file)
index 1e0989d..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-import re
-import urllib.parse
-
-from .common import InfoExtractor
-from ..compat import compat_urllib_parse_unquote
-from ..utils import ExtractorError, clean_html
-
-
-class PlayvidIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?playvid\.com/watch(\?v=|/)(?P<id>.+?)(?:#|$)'
-    _TESTS = [{
-        'url': 'http://www.playvid.com/watch/RnmBNgtrrJu',
-        'md5': 'ffa2f6b2119af359f544388d8c01eb6c',
-        'info_dict': {
-            'id': 'RnmBNgtrrJu',
-            'ext': 'mp4',
-            'title': 'md5:9256d01c6317e3f703848b5906880dc8',
-            'duration': 82,
-            'age_limit': 18,
-        },
-        'skip': 'Video removed due to ToS',
-    }, {
-        'url': 'http://www.playvid.com/watch/hwb0GpNkzgH',
-        'md5': '39d49df503ad7b8f23a4432cbf046477',
-        'info_dict': {
-            'id': 'hwb0GpNkzgH',
-            'ext': 'mp4',
-            'title': 'Ellen Euro Cutie Blond Takes a Sexy Survey Get Facial in The Park',
-            'age_limit': 18,
-            'thumbnail': r're:^https?://.*\.jpg$',
-        },
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-
-        m_error = re.search(
-            r'<div class="block-error">\s*<div class="heading">\s*<div>(?P<msg>.+?)</div>\s*</div>', webpage)
-        if m_error:
-            raise ExtractorError(clean_html(m_error.group('msg')), expected=True)
-
-        video_title = None
-        duration = None
-        video_thumbnail = None
-        formats = []
-
-        # most of the information is stored in the flashvars
-        flashvars = self._html_search_regex(
-            r'flashvars="(.+?)"', webpage, 'flashvars')
-
-        infos = compat_urllib_parse_unquote(flashvars).split(r'&')
-        for info in infos:
-            videovars_match = re.match(r'^video_vars\[(.+?)\]=(.+?)$', info)
-            if videovars_match:
-                key = videovars_match.group(1)
-                val = videovars_match.group(2)
-
-                if key == 'title':
-                    video_title = urllib.parse.unquote_plus(val)
-                if key == 'duration':
-                    try:
-                        duration = int(val)
-                    except ValueError:
-                        pass
-                if key == 'big_thumb':
-                    video_thumbnail = val
-
-                videourl_match = re.match(
-                    r'^video_urls\]\[(?P<resolution>[0-9]+)p', key)
-                if videourl_match:
-                    height = int(videourl_match.group('resolution'))
-                    formats.append({
-                        'height': height,
-                        'url': val,
-                    })
-
-        # Extract title - should be in the flashvars; if not, look elsewhere
-        if video_title is None:
-            video_title = self._html_extract_title(webpage)
-
-        return {
-            'id': video_id,
-            'formats': formats,
-            'title': video_title,
-            'thumbnail': video_thumbnail,
-            'duration': duration,
-            'description': None,
-            'age_limit': 18
-        }
diff --git a/yt_dlp/extractor/porncom.py b/yt_dlp/extractor/porncom.py
deleted file mode 100644 (file)
index c8ef240..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..compat import compat_urlparse
-from ..utils import (
-    int_or_none,
-    js_to_json,
-    parse_filesize,
-    str_to_int,
-)
-
-
-class PornComIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:[a-zA-Z]+\.)?porn\.com/videos/(?:(?P<display_id>[^/]+)-)?(?P<id>\d+)'
-    _TESTS = [{
-        'url': 'http://www.porn.com/videos/teen-grabs-a-dildo-and-fucks-her-pussy-live-on-1hottie-i-rec-2603339',
-        'md5': '3f30ce76267533cd12ba999263156de7',
-        'info_dict': {
-            'id': '2603339',
-            'display_id': 'teen-grabs-a-dildo-and-fucks-her-pussy-live-on-1hottie-i-rec',
-            'ext': 'mp4',
-            'title': 'Teen grabs a dildo and fucks her pussy live on 1hottie, I rec',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'duration': 551,
-            'view_count': int,
-            'age_limit': 18,
-            'categories': list,
-            'tags': list,
-        },
-    }, {
-        'url': 'http://se.porn.com/videos/marsha-may-rides-seth-on-top-of-his-thick-cock-2658067',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        mobj = self._match_valid_url(url)
-        video_id = mobj.group('id')
-        display_id = mobj.group('display_id') or video_id
-
-        webpage = self._download_webpage(url, display_id)
-
-        config = self._parse_json(
-            self._search_regex(
-                (r'=\s*({.+?})\s*;\s*v1ar\b',
-                 r'=\s*({.+?})\s*,\s*[\da-zA-Z_]+\s*='),
-                webpage, 'config', default='{}'),
-            display_id, transform_source=js_to_json, fatal=False)
-
-        if config:
-            title = config['title']
-            formats = [{
-                'url': stream['url'],
-                'format_id': stream.get('id'),
-                'height': int_or_none(self._search_regex(
-                    r'^(\d+)[pP]', stream.get('id') or '', 'height', default=None))
-            } for stream in config['streams'] if stream.get('url')]
-            thumbnail = (compat_urlparse.urljoin(
-                config['thumbCDN'], config['poster'])
-                if config.get('thumbCDN') and config.get('poster') else None)
-            duration = int_or_none(config.get('length'))
-        else:
-            title = self._search_regex(
-                (r'<title>([^<]+)</title>', r'<h1[^>]*>([^<]+)</h1>'),
-                webpage, 'title')
-            formats = [{
-                'url': compat_urlparse.urljoin(url, format_url),
-                'format_id': '%sp' % height,
-                'height': int(height),
-                'filesize_approx': parse_filesize(filesize),
-            } for format_url, height, filesize in re.findall(
-                r'<a[^>]+href="(/download/[^"]+)">[^<]*?(\d+)p<span[^>]*>(\d+\s*[a-zA-Z]+)<',
-                webpage)]
-            thumbnail = None
-            duration = None
-
-        view_count = str_to_int(self._search_regex(
-            (r'Views:\s*</span>\s*<span>\s*([\d,.]+)',
-             r'class=["\']views["\'][^>]*><p>([\d,.]+)'), webpage,
-            'view count', fatal=False))
-
-        def extract_list(kind):
-            s = self._search_regex(
-                (r'(?s)%s:\s*</span>\s*<span>(.+?)</span>' % kind.capitalize(),
-                 r'(?s)<p[^>]*>%s:(.+?)</p>' % kind.capitalize()),
-                webpage, kind, fatal=False)
-            return re.findall(r'<a[^>]+>([^<]+)</a>', s or '')
-
-        return {
-            'id': video_id,
-            'display_id': display_id,
-            'title': title,
-            'thumbnail': thumbnail,
-            'duration': duration,
-            'view_count': view_count,
-            'formats': formats,
-            'age_limit': 18,
-            'categories': extract_list('categories'),
-            'tags': extract_list('tags'),
-        }
diff --git a/yt_dlp/extractor/pornez.py b/yt_dlp/extractor/pornez.py
deleted file mode 100644 (file)
index bc45f86..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    clean_html,
-    int_or_none,
-    get_element_by_class,
-    urljoin,
-)
-
-
-class PornezIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?pornez\.net/(?:video(?P<id>\w+)|watch)/'
-    _TESTS = [{
-        'url': 'https://pornez.net/video344819/mistresst-funny_penis_names-wmv/',
-        'info_dict': {
-            'id': '344819',
-            'ext': 'mp4',
-            'title': 'mistresst funny_penis_names wmv',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'age_limit': 18,
-        },
-        'params': {'skip_download': 'm3u8'},
-    }, {
-        'url': 'https://pornez.net/watch/leana+lovings+stiff+for+stepdaughter/',
-        'info_dict': {
-            'id': '156161',
-            'ext': 'mp4',
-            'title': 'Watch leana lovings stiff for stepdaughter porn video.',
-            'age_limit': 18,
-        },
-        'params': {'skip_download': 'm3u8'},
-    }, {
-        'url': 'https://pornez.net/videovzs27fj/tutor4k-e14-blue-wave-1080p-nbq-tutor4k-e14-blue-wave/',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-        if not video_id:
-            video_id = self._search_regex(
-                r'<link[^>]+\bhref=["\']https?://pornez.net/\?p=(\w+)["\']', webpage, 'id')
-
-        iframe_src = self._html_search_regex(r'<iframe[^>]+src="([^"]+)"', webpage, 'iframe')
-        iframe = self._download_webpage(urljoin('https://pornez.net', iframe_src), video_id)
-
-        entries = self._parse_html5_media_entries(iframe_src, iframe, video_id)[0]
-        for fmt in entries['formats']:
-            height = self._search_regex(r'_(\d+)\.m3u8', fmt['url'], 'height')
-            fmt['format_id'] = '%sp' % height
-            fmt['height'] = int_or_none(height)
-
-        entries.update({
-            'id': video_id,
-            'title': (clean_html(get_element_by_class('video-title', webpage))
-                      or self._html_search_meta(
-                      ['twitter:title', 'og:title', 'description'], webpage, 'title', default=None)),
-            'thumbnail': self._html_search_meta(['thumbnailUrl'], webpage, 'thumb', default=None),
-            'age_limit': 18,
-        })
-        return entries
diff --git a/yt_dlp/extractor/pornhd.py b/yt_dlp/extractor/pornhd.py
deleted file mode 100644 (file)
index c8a1ec8..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    determine_ext,
-    ExtractorError,
-    int_or_none,
-    js_to_json,
-    merge_dicts,
-    urljoin,
-)
-
-
-class PornHdIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?pornhd\.com/(?:[a-z]{2,4}/)?videos/(?P<id>\d+)(?:/(?P<display_id>.+))?'
-    _TESTS = [{
-        'url': 'http://www.pornhd.com/videos/9864/selfie-restroom-masturbation-fun-with-chubby-cutie-hd-porn-video',
-        'md5': '87f1540746c1d32ec7a2305c12b96b25',
-        'info_dict': {
-            'id': '9864',
-            'display_id': 'selfie-restroom-masturbation-fun-with-chubby-cutie-hd-porn-video',
-            'ext': 'mp4',
-            'title': 'Restroom selfie masturbation',
-            'description': 'md5:3748420395e03e31ac96857a8f125b2b',
-            'thumbnail': r're:^https?://.*\.jpg',
-            'view_count': int,
-            'like_count': int,
-            'age_limit': 18,
-        },
-        'skip': 'HTTP Error 404: Not Found',
-    }, {
-        'url': 'http://www.pornhd.com/videos/1962/sierra-day-gets-his-cum-all-over-herself-hd-porn-video',
-        'md5': '1b7b3a40b9d65a8e5b25f7ab9ee6d6de',
-        'info_dict': {
-            'id': '1962',
-            'display_id': 'sierra-day-gets-his-cum-all-over-herself-hd-porn-video',
-            'ext': 'mp4',
-            'title': 'md5:98c6f8b2d9c229d0f0fde47f61a1a759',
-            'description': 'md5:8ff0523848ac2b8f9b065ba781ccf294',
-            'thumbnail': r're:^https?://.*\.jpg',
-            'view_count': int,
-            'like_count': int,
-            'age_limit': 18,
-        },
-    }]
-
-    def _real_extract(self, url):
-        mobj = self._match_valid_url(url)
-        video_id = mobj.group('id')
-        display_id = mobj.group('display_id')
-
-        webpage = self._download_webpage(url, display_id or video_id)
-
-        title = self._html_search_regex(
-            [r'<span[^>]+class=["\']video-name["\'][^>]*>([^<]+)',
-             r'<title>(.+?) - .*?[Pp]ornHD.*?</title>'], webpage, 'title')
-
-        sources = self._parse_json(js_to_json(self._search_regex(
-            r"(?s)sources'?\s*[:=]\s*(\{.+?\})",
-            webpage, 'sources', default='{}')), video_id)
-
-        info = {}
-        if not sources:
-            entries = self._parse_html5_media_entries(url, webpage, video_id)
-            if entries:
-                info = entries[0]
-
-        if not sources and not info:
-            message = self._html_search_regex(
-                r'(?s)<(div|p)[^>]+class="no-video"[^>]*>(?P<value>.+?)</\1',
-                webpage, 'error message', group='value')
-            raise ExtractorError('%s said: %s' % (self.IE_NAME, message), expected=True)
-
-        formats = []
-        for format_id, video_url in sources.items():
-            video_url = urljoin(url, video_url)
-            if not video_url:
-                continue
-            height = int_or_none(self._search_regex(
-                r'^(\d+)[pP]', format_id, 'height', default=None))
-            formats.append({
-                'url': video_url,
-                'ext': determine_ext(video_url, 'mp4'),
-                'format_id': format_id,
-                'height': height,
-            })
-        if formats:
-            info['formats'] = formats
-
-        description = self._html_search_regex(
-            (r'(?s)<section[^>]+class=["\']video-description[^>]+>(?P<value>.+?)</section>',
-             r'<(div|p)[^>]+class="description"[^>]*>(?P<value>[^<]+)</\1'),
-            webpage, 'description', fatal=False,
-            group='value') or self._html_search_meta(
-            'description', webpage, default=None) or self._og_search_description(webpage)
-        view_count = int_or_none(self._html_search_regex(
-            r'(\d+) views\s*<', webpage, 'view count', fatal=False))
-        thumbnail = self._search_regex(
-            r"poster'?\s*:\s*([\"'])(?P<url>(?:(?!\1).)+)\1", webpage,
-            'thumbnail', default=None, group='url')
-
-        like_count = int_or_none(self._search_regex(
-            (r'(\d+)</span>\s*likes',
-             r'(\d+)\s*</11[^>]+>(?:&nbsp;|\s)*\blikes',
-             r'class=["\']save-count["\'][^>]*>\s*(\d+)'),
-            webpage, 'like count', fatal=False))
-
-        return merge_dicts(info, {
-            'id': video_id,
-            'display_id': display_id,
-            'title': title,
-            'description': description,
-            'thumbnail': thumbnail,
-            'view_count': view_count,
-            'like_count': like_count,
-            'formats': formats,
-            'age_limit': 18,
-        })
diff --git a/yt_dlp/extractor/radiobremen.py b/yt_dlp/extractor/radiobremen.py
deleted file mode 100644 (file)
index 99ba050..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..utils import parse_duration
-
-
-class RadioBremenIE(InfoExtractor):
-    _VALID_URL = r'http?://(?:www\.)?radiobremen\.de/mediathek/(?:index\.html)?\?id=(?P<id>[0-9]+)'
-    IE_NAME = 'radiobremen'
-
-    _TEST = {
-        'url': 'http://www.radiobremen.de/mediathek/?id=141876',
-        'info_dict': {
-            'id': '141876',
-            'ext': 'mp4',
-            'duration': 178,
-            'width': 512,
-            'title': 'Druck auf Patrick Öztürk',
-            'thumbnail': r're:https?://.*\.jpg$',
-            'description': 'Gegen den SPD-Bürgerschaftsabgeordneten Patrick Öztürk wird wegen Beihilfe zum gewerbsmäßigen Betrug ermittelt. Am Donnerstagabend sollte er dem Vorstand des SPD-Unterbezirks Bremerhaven dazu Rede und Antwort stehen.',
-        },
-    }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        meta_url = 'http://www.radiobremen.de/apps/php/mediathek/metadaten.php?id=%s' % video_id
-        meta_doc = self._download_webpage(
-            meta_url, video_id, 'Downloading metadata')
-        title = self._html_search_regex(
-            r'<h1.*>(?P<title>.+)</h1>', meta_doc, 'title')
-        description = self._html_search_regex(
-            r'<p>(?P<description>.*)</p>', meta_doc, 'description', fatal=False)
-        duration = parse_duration(self._html_search_regex(
-            r'L&auml;nge:</td>\s+<td>(?P<duration>[0-9]+:[0-9]+)</td>',
-            meta_doc, 'duration', fatal=False))
-
-        page_doc = self._download_webpage(
-            url, video_id, 'Downloading video information')
-        mobj = re.search(
-            r"ardformatplayerclassic\(\'playerbereich\',\'(?P<width>[0-9]+)\',\'.*\',\'(?P<video_id>[0-9]+)\',\'(?P<secret>[0-9]+)\',\'(?P<thumbnail>.+)\',\'\'\)",
-            page_doc)
-        video_url = (
-            "http://dl-ondemand.radiobremen.de/mediabase/%s/%s_%s_%s.mp4" %
-            (video_id, video_id, mobj.group("secret"), mobj.group('width')))
-
-        formats = [{
-            'url': video_url,
-            'ext': 'mp4',
-            'width': int(mobj.group('width')),
-        }]
-        return {
-            'id': video_id,
-            'title': title,
-            'description': description,
-            'duration': duration,
-            'formats': formats,
-            'thumbnail': mobj.group('thumbnail'),
-        }
diff --git a/yt_dlp/extractor/recurbate.py b/yt_dlp/extractor/recurbate.py
deleted file mode 100644 (file)
index d7294cb..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-from .common import InfoExtractor
-from ..networking.exceptions import HTTPError
-from ..utils import ExtractorError, merge_dicts
-
-
-class RecurbateIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?recurbate\.com/play\.php\?video=(?P<id>\d+)'
-    _TESTS = [{
-        'url': 'https://recurbate.com/play.php?video=39161415',
-        'md5': 'dd2b4ec57aa3e3572cb5cf0997fca99f',
-        'info_dict': {
-            'id': '39161415',
-            'ext': 'mp4',
-            'description': 'md5:db48d09e4d93fc715f47fd3d6b7edd51',
-            'title': 'Performer zsnicole33 show on 2022-10-25 20:23, Chaturbate Archive – Recurbate',
-            'age_limit': 18,
-        },
-        'skip': 'Website require membership.',
-    }]
-
-    def _real_extract(self, url):
-        SUBSCRIPTION_MISSING_MESSAGE = 'This video is only available for registered users; Set your authenticated browser user agent via the --user-agent parameter.'
-        video_id = self._match_id(url)
-        try:
-            webpage = self._download_webpage(url, video_id)
-        except ExtractorError as e:
-            if isinstance(e.cause, HTTPError) and e.cause.status == 403:
-                self.raise_login_required(msg=SUBSCRIPTION_MISSING_MESSAGE, method='cookies')
-            raise
-        token = self._html_search_regex(r'data-token="([^"]+)"', webpage, 'token')
-        video_url = f'https://recurbate.com/api/get.php?video={video_id}&token={token}'
-
-        video_webpage = self._download_webpage(video_url, video_id)
-        if video_webpage == 'shall_subscribe':
-            self.raise_login_required(msg=SUBSCRIPTION_MISSING_MESSAGE, method='cookies')
-        entries = self._parse_html5_media_entries(video_url, video_webpage, video_id)
-        return merge_dicts({
-            'id': video_id,
-            'title': self._html_extract_title(webpage, 'title'),
-            'description': self._og_search_description(webpage),
-            'age_limit': self._rta_search(webpage),
-        }, entries[0])
diff --git a/yt_dlp/extractor/rice.py b/yt_dlp/extractor/rice.py
deleted file mode 100644 (file)
index 3dd4d31..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..compat import compat_parse_qs
-from ..utils import (
-    xpath_text,
-    xpath_element,
-    int_or_none,
-    parse_iso8601,
-    ExtractorError,
-)
-
-
-class RICEIE(InfoExtractor):
-    _VALID_URL = r'https?://mediahub\.rice\.edu/app/[Pp]ortal/video\.aspx\?(?P<query>.+)'
-    _TEST = {
-        'url': 'https://mediahub.rice.edu/app/Portal/video.aspx?PortalID=25ffd62c-3d01-4b29-8c70-7c94270efb3e&DestinationID=66bc9434-03bd-4725-b47e-c659d8d809db&ContentID=YEWIvbhb40aqdjMD1ALSqw',
-        'md5': '9b83b4a2eead4912dc3b7fac7c449b6a',
-        'info_dict': {
-            'id': 'YEWIvbhb40aqdjMD1ALSqw',
-            'ext': 'mp4',
-            'title': 'Active Learning in Archeology',
-            'upload_date': '20140616',
-            'timestamp': 1402926346,
-        }
-    }
-    _NS = 'http://schemas.datacontract.org/2004/07/ensembleVideo.Data.Service.Contracts.Models.Player.Config'
-
-    def _real_extract(self, url):
-        qs = compat_parse_qs(self._match_valid_url(url).group('query'))
-        if not qs.get('PortalID') or not qs.get('DestinationID') or not qs.get('ContentID'):
-            raise ExtractorError('Invalid URL', expected=True)
-
-        portal_id = qs['PortalID'][0]
-        playlist_id = qs['DestinationID'][0]
-        content_id = qs['ContentID'][0]
-
-        content_data = self._download_xml('https://mediahub.rice.edu/api/portal/GetContentTitle', content_id, query={
-            'portalId': portal_id,
-            'playlistId': playlist_id,
-            'contentId': content_id
-        })
-        metadata = xpath_element(content_data, './/metaData', fatal=True)
-        title = xpath_text(metadata, 'primaryTitle', fatal=True)
-        encodings = xpath_element(content_data, './/encodings', fatal=True)
-        player_data = self._download_xml('https://mediahub.rice.edu/api/player/GetPlayerConfig', content_id, query={
-            'temporaryLinkId': xpath_text(encodings, 'temporaryLinkId', fatal=True),
-            'contentId': content_id,
-        })
-
-        common_fmt = {}
-        dimensions = xpath_text(encodings, 'dimensions')
-        if dimensions:
-            wh = dimensions.split('x')
-            if len(wh) == 2:
-                common_fmt.update({
-                    'width': int_or_none(wh[0]),
-                    'height': int_or_none(wh[1]),
-                })
-
-        formats = []
-        rtsp_path = xpath_text(player_data, self._xpath_ns('RtspPath', self._NS))
-        if rtsp_path:
-            fmt = {
-                'url': rtsp_path,
-                'format_id': 'rtsp',
-            }
-            fmt.update(common_fmt)
-            formats.append(fmt)
-        for source in player_data.findall(self._xpath_ns('.//Source', self._NS)):
-            video_url = xpath_text(source, self._xpath_ns('File', self._NS))
-            if not video_url:
-                continue
-            if '.m3u8' in video_url:
-                formats.extend(self._extract_m3u8_formats(video_url, content_id, 'mp4', 'm3u8_native', m3u8_id='hls', fatal=False))
-            else:
-                fmt = {
-                    'url': video_url,
-                    'format_id': video_url.split(':')[0],
-                }
-                fmt.update(common_fmt)
-                rtmp = re.search(r'^(?P<url>rtmp://[^/]+/(?P<app>.+))/(?P<playpath>mp4:.+)$', video_url)
-                if rtmp:
-                    fmt.update({
-                        'url': rtmp.group('url'),
-                        'play_path': rtmp.group('playpath'),
-                        'app': rtmp.group('app'),
-                        'ext': 'flv',
-                    })
-                formats.append(fmt)
-
-        thumbnails = []
-        for content_asset in content_data.findall('.//contentAssets'):
-            asset_type = xpath_text(content_asset, 'type')
-            if asset_type == 'image':
-                image_url = xpath_text(content_asset, 'httpPath')
-                if not image_url:
-                    continue
-                thumbnails.append({
-                    'id': xpath_text(content_asset, 'ID'),
-                    'url': image_url,
-                })
-
-        return {
-            'id': content_id,
-            'title': title,
-            'description': xpath_text(metadata, 'abstract'),
-            'duration': int_or_none(xpath_text(metadata, 'duration')),
-            'timestamp': parse_iso8601(xpath_text(metadata, 'dateUpdated')),
-            'thumbnails': thumbnails,
-            'formats': formats,
-        }
index 056cf87d2929198ed783aa2841786fad9bef1d53..07e1aa3ce43e1869128c81e199ba801b4c076534 100644 (file)
@@ -1,16 +1,7 @@
 import re
 
 from .common import InfoExtractor
 import re
 
 from .common import InfoExtractor
-from ..aes import aes_cbc_decrypt_bytes, unpad_pkcs7
-from ..compat import (
-    compat_b64decode,
-    compat_str,
-)
-from ..utils import (
-    ExtractorError,
-    int_or_none,
-    strip_or_none,
-)
+from ..utils import int_or_none
 
 
 class RTL2IE(InfoExtractor):
 
 
 class RTL2IE(InfoExtractor):
@@ -102,92 +93,3 @@ def _real_extract(self, url):
             'duration': int_or_none(video_info.get('duration')),
             'formats': formats,
         }
             'duration': int_or_none(video_info.get('duration')),
             'formats': formats,
         }
-
-
-class RTL2YouBaseIE(InfoExtractor):
-    _BACKWERK_BASE_URL = 'https://p-you-backwerk.rtl2apps.de/'
-
-
-class RTL2YouIE(RTL2YouBaseIE):
-    IE_NAME = 'rtl2:you'
-    _VALID_URL = r'http?://you\.rtl2\.de/(?:video/\d+/|youplayer/index\.html\?.*?\bvid=)(?P<id>\d+)'
-    _TESTS = [{
-        'url': 'http://you.rtl2.de/video/3002/15740/MJUNIK%20%E2%80%93%20Home%20of%20YOU/307-hirn-wo-bist-du',
-        'info_dict': {
-            'id': '15740',
-            'ext': 'mp4',
-            'title': 'MJUNIK – Home of YOU - #307 Hirn, wo bist du?!',
-            'description': 'md5:ddaa95c61b372b12b66e115b2772fe01',
-            'age_limit': 12,
-        },
-    }, {
-        'url': 'http://you.rtl2.de/youplayer/index.html?vid=15712',
-        'only_matching': True,
-    }]
-    _AES_KEY = b'\xe9W\xe4.<*\xb8\x1a\xd2\xb6\x92\xf3C\xd3\xefL\x1b\x03*\xbbbH\xc0\x03\xffo\xc2\xf2(\xaa\xaa!'
-    _GEO_COUNTRIES = ['DE']
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        stream_data = self._download_json(
-            self._BACKWERK_BASE_URL + 'stream/video/' + video_id, video_id)
-
-        data, iv = compat_b64decode(stream_data['streamUrl']).decode().split(':')
-        stream_url = unpad_pkcs7(aes_cbc_decrypt_bytes(
-            compat_b64decode(data), self._AES_KEY, compat_b64decode(iv)))
-        if b'rtl2_you_video_not_found' in stream_url:
-            raise ExtractorError('video not found', expected=True)
-
-        formats = self._extract_m3u8_formats(stream_url.decode(), video_id, 'mp4', 'm3u8_native')
-
-        video_data = self._download_json(
-            self._BACKWERK_BASE_URL + 'video/' + video_id, video_id)
-
-        series = video_data.get('formatTitle')
-        title = episode = video_data.get('title') or series
-        if series and series != title:
-            title = '%s - %s' % (series, title)
-
-        return {
-            'id': video_id,
-            'title': title,
-            'formats': formats,
-            'description': strip_or_none(video_data.get('description')),
-            'thumbnail': video_data.get('image'),
-            'duration': int_or_none(stream_data.get('duration') or video_data.get('duration'), 1000),
-            'series': series,
-            'episode': episode,
-            'age_limit': int_or_none(video_data.get('minimumAge')),
-        }
-
-
-class RTL2YouSeriesIE(RTL2YouBaseIE):
-    IE_NAME = 'rtl2:you:series'
-    _VALID_URL = r'http?://you\.rtl2\.de/videos/(?P<id>\d+)'
-    _TEST = {
-        'url': 'http://you.rtl2.de/videos/115/dragon-ball',
-        'info_dict': {
-            'id': '115',
-        },
-        'playlist_mincount': 5,
-    }
-
-    def _real_extract(self, url):
-        series_id = self._match_id(url)
-        stream_data = self._download_json(
-            self._BACKWERK_BASE_URL + 'videos',
-            series_id, query={
-                'formatId': series_id,
-                'limit': 1000000000,
-            })
-
-        entries = []
-        for video in stream_data.get('videos', []):
-            video_id = compat_str(video['videoId'])
-            if not video_id:
-                continue
-            entries.append(self.url_result(
-                'http://you.rtl2.de/video/%s/%s' % (series_id, video_id),
-                'RTL2You', video_id))
-        return self.playlist_result(entries, series_id)
diff --git a/yt_dlp/extractor/rtvnh.py b/yt_dlp/extractor/rtvnh.py
deleted file mode 100644 (file)
index 7c61744..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-from .common import InfoExtractor
-from ..utils import ExtractorError
-
-
-class RTVNHIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?rtvnh\.nl/video/(?P<id>[0-9]+)'
-    _TEST = {
-        'url': 'http://www.rtvnh.nl/video/131946',
-        'md5': 'cdbec9f44550763c8afc96050fa747dc',
-        'info_dict': {
-            'id': '131946',
-            'ext': 'mp4',
-            'title': 'Grote zoektocht in zee bij Zandvoort naar vermiste vrouw',
-            'thumbnail': r're:^https?:.*\.jpg$'
-        }
-    }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        meta = self._parse_json(self._download_webpage(
-            'http://www.rtvnh.nl/video/json?m=' + video_id, video_id), video_id)
-
-        status = meta.get('status')
-        if status != 200:
-            raise ExtractorError(
-                '%s returned error code %d' % (self.IE_NAME, status), expected=True)
-
-        formats = []
-        rtmp_formats = self._extract_smil_formats(
-            'http://www.rtvnh.nl/video/smil?m=' + video_id, video_id)
-        formats.extend(rtmp_formats)
-
-        for rtmp_format in rtmp_formats:
-            rtmp_url = '%s/%s' % (rtmp_format['url'], rtmp_format['play_path'])
-            rtsp_format = rtmp_format.copy()
-            del rtsp_format['play_path']
-            del rtsp_format['ext']
-            rtsp_format.update({
-                'format_id': rtmp_format['format_id'].replace('rtmp', 'rtsp'),
-                'url': rtmp_url.replace('rtmp://', 'rtsp://'),
-                'protocol': 'rtsp',
-            })
-            formats.append(rtsp_format)
-            http_base_url = rtmp_url.replace('rtmp://', 'http://')
-            formats.extend(self._extract_m3u8_formats(
-                http_base_url + '/playlist.m3u8', video_id, 'mp4',
-                'm3u8_native', m3u8_id='hls', fatal=False))
-            formats.extend(self._extract_f4m_formats(
-                http_base_url + '/manifest.f4m',
-                video_id, f4m_id='hds', fatal=False))
-
-        return {
-            'id': video_id,
-            'title': meta['title'].strip(),
-            'thumbnail': meta.get('image'),
-            'formats': formats
-        }
diff --git a/yt_dlp/extractor/ruhd.py b/yt_dlp/extractor/ruhd.py
deleted file mode 100644 (file)
index abaa3f9..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-from .common import InfoExtractor
-
-
-class RUHDIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?ruhd\.ru/play\.php\?vid=(?P<id>\d+)'
-    _TEST = {
-        'url': 'http://www.ruhd.ru/play.php?vid=207',
-        'md5': 'd1a9ec4edf8598e3fbd92bb16072ba83',
-        'info_dict': {
-            'id': '207',
-            'ext': 'divx',
-            'title': 'КОТ бааааам',
-            'description': 'классный кот)',
-            'thumbnail': r're:^http://.*\.jpg$',
-        }
-    }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-
-        video_url = self._html_search_regex(
-            r'<param name="src" value="([^"]+)"', webpage, 'video url')
-        title = self._html_search_regex(
-            r'<title>([^<]+)&nbsp;&nbsp; RUHD\.ru - Видео Высокого качества №1 в России!</title>',
-            webpage, 'title')
-        description = self._html_search_regex(
-            r'(?s)<div id="longdesc">(.+?)<span id="showlink">',
-            webpage, 'description', fatal=False)
-        thumbnail = self._html_search_regex(
-            r'<param name="previewImage" value="([^"]+)"',
-            webpage, 'thumbnail', fatal=False)
-        if thumbnail:
-            thumbnail = 'http://www.ruhd.ru' + thumbnail
-
-        return {
-            'id': video_id,
-            'url': video_url,
-            'title': title,
-            'description': description,
-            'thumbnail': thumbnail,
-        }
index d839ffcde8d8f485bac2ec5bbb8e076f752a1a85..9c2ca8c5185ca3dfff3ee4b470bc96f40d1bc22c 100644 (file)
@@ -46,6 +46,7 @@ def is_logged(webpage):
 
 
 class SCTEIE(SCTEBaseIE):
 
 
 class SCTEIE(SCTEBaseIE):
+    _WORKING = False
     _VALID_URL = r'https?://learning\.scte\.org/mod/scorm/view\.php?.*?\bid=(?P<id>\d+)'
     _TESTS = [{
         'url': 'https://learning.scte.org/mod/scorm/view.php?id=31484',
     _VALID_URL = r'https?://learning\.scte\.org/mod/scorm/view\.php?.*?\bid=(?P<id>\d+)'
     _TESTS = [{
         'url': 'https://learning.scte.org/mod/scorm/view.php?id=31484',
@@ -93,6 +94,7 @@ def _real_extract(self, url):
 
 
 class SCTECourseIE(SCTEBaseIE):
 
 
 class SCTECourseIE(SCTEBaseIE):
+    _WORKING = False
     _VALID_URL = r'https?://learning\.scte\.org/(?:mod/sub)?course/view\.php?.*?\bid=(?P<id>\d+)'
     _TESTS = [{
         'url': 'https://learning.scte.org/mod/subcourse/view.php?id=31491',
     _VALID_URL = r'https?://learning\.scte\.org/(?:mod/sub)?course/view\.php?.*?\bid=(?P<id>\d+)'
     _TESTS = [{
         'url': 'https://learning.scte.org/mod/subcourse/view.php?id=31491',
diff --git a/yt_dlp/extractor/shared.py b/yt_dlp/extractor/shared.py
deleted file mode 100644 (file)
index 9a237b3..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-import urllib.parse
-
-from .common import InfoExtractor
-from ..compat import compat_b64decode
-from ..utils import (
-    KNOWN_EXTENSIONS,
-    ExtractorError,
-    determine_ext,
-    int_or_none,
-    js_to_json,
-    parse_filesize,
-    rot47,
-    url_or_none,
-    urlencode_postdata,
-)
-
-
-class SharedBaseIE(InfoExtractor):
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        webpage, urlh = self._download_webpage_handle(url, video_id)
-
-        if self._FILE_NOT_FOUND in webpage:
-            raise ExtractorError(
-                'Video %s does not exist' % video_id, expected=True)
-
-        video_url = self._extract_video_url(webpage, video_id, url)
-
-        title = self._extract_title(webpage)
-        filesize = int_or_none(self._extract_filesize(webpage))
-
-        return {
-            'id': video_id,
-            'url': video_url,
-            'ext': 'mp4',
-            'filesize': filesize,
-            'title': title,
-        }
-
-    def _extract_title(self, webpage):
-        return compat_b64decode(self._html_search_meta(
-            'full:title', webpage, 'title')).decode('utf-8')
-
-    def _extract_filesize(self, webpage):
-        return self._html_search_meta(
-            'full:size', webpage, 'file size', fatal=False)
-
-
-class SharedIE(SharedBaseIE):
-    IE_DESC = 'shared.sx'
-    _VALID_URL = r'https?://shared\.sx/(?P<id>[\da-z]{10})'
-    _FILE_NOT_FOUND = '>File does not exist<'
-
-    _TEST = {
-        'url': 'http://shared.sx/0060718775',
-        'md5': '106fefed92a8a2adb8c98e6a0652f49b',
-        'info_dict': {
-            'id': '0060718775',
-            'ext': 'mp4',
-            'title': 'Bmp4',
-            'filesize': 1720110,
-        },
-    }
-
-    def _extract_video_url(self, webpage, video_id, url):
-        download_form = self._hidden_inputs(webpage)
-
-        video_page = self._download_webpage(
-            url, video_id, 'Downloading video page',
-            data=urlencode_postdata(download_form),
-            headers={
-                'Content-Type': 'application/x-www-form-urlencoded',
-                'Referer': url,
-            })
-
-        video_url = self._html_search_regex(
-            r'data-url=(["\'])(?P<url>(?:(?!\1).)+)\1',
-            video_page, 'video URL', group='url')
-
-        return video_url
-
-
-class VivoIE(SharedBaseIE):
-    IE_DESC = 'vivo.sx'
-    _VALID_URL = r'https?://vivo\.s[xt]/(?P<id>[\da-z]{10})'
-    _FILE_NOT_FOUND = '>The file you have requested does not exists or has been removed'
-
-    _TESTS = [{
-        'url': 'http://vivo.sx/d7ddda0e78',
-        'md5': '15b3af41be0b4fe01f4df075c2678b2c',
-        'info_dict': {
-            'id': 'd7ddda0e78',
-            'ext': 'mp4',
-            'title': 'Chicken',
-            'filesize': 515659,
-        },
-    }, {
-        'url': 'http://vivo.st/d7ddda0e78',
-        'only_matching': True,
-    }]
-
-    def _extract_title(self, webpage):
-        title = self._html_search_regex(
-            r'data-name\s*=\s*(["\'])(?P<title>(?:(?!\1).)+)\1', webpage,
-            'title', default=None, group='title')
-        if title:
-            ext = determine_ext(title)
-            if ext.lower() in KNOWN_EXTENSIONS:
-                title = title.rpartition('.' + ext)[0]
-            return title
-        return self._og_search_title(webpage)
-
-    def _extract_filesize(self, webpage):
-        return parse_filesize(self._search_regex(
-            r'data-type=["\']video["\'][^>]*>Watch.*?<strong>\s*\((.+?)\)',
-            webpage, 'filesize', fatal=False))
-
-    def _extract_video_url(self, webpage, video_id, url):
-        def decode_url_old(encoded_url):
-            return compat_b64decode(encoded_url).decode('utf-8')
-
-        stream_url = self._search_regex(
-            r'data-stream\s*=\s*(["\'])(?P<url>(?:(?!\1).)+)\1', webpage,
-            'stream url', default=None, group='url')
-        if stream_url:
-            stream_url = url_or_none(decode_url_old(stream_url))
-        if stream_url:
-            return stream_url
-
-        def decode_url(encoded_url):
-            return rot47(urllib.parse.unquote_plus(encoded_url))
-
-        return decode_url(self._parse_json(
-            self._search_regex(
-                r'(?s)InitializeStream\s*\(\s*({.+?})\s*\)\s*;', webpage,
-                'stream'),
-            video_id, transform_source=js_to_json)['source'])
index 0a8b6cc76946cd3a511bec0f9037eebfb8d4008e..574ac219cc7e5225d3e4f2ada08a21d9c224b2dc 100644 (file)
@@ -3,9 +3,7 @@
 from .common import InfoExtractor
 from ..utils import (
     extract_attributes,
 from .common import InfoExtractor
 from ..utils import (
     extract_attributes,
-    smuggle_url,
     strip_or_none,
     strip_or_none,
-    urljoin,
 )
 
 
 )
 
 
@@ -13,29 +11,10 @@ class SkyBaseIE(InfoExtractor):
     BRIGHTCOVE_URL_TEMPLATE = 'http://players.brightcove.net/%s/%s_default/index.html?videoId=%s'
     _SDC_EL_REGEX = r'(?s)(<div[^>]+data-(?:component-name|fn)="sdc-(?:articl|sit)e-video"[^>]*>)'
 
     BRIGHTCOVE_URL_TEMPLATE = 'http://players.brightcove.net/%s/%s_default/index.html?videoId=%s'
     _SDC_EL_REGEX = r'(?s)(<div[^>]+data-(?:component-name|fn)="sdc-(?:articl|sit)e-video"[^>]*>)'
 
-    def _process_ooyala_element(self, webpage, sdc_el, url):
+    def _process_video_element(self, webpage, sdc_el, url):
         sdc = extract_attributes(sdc_el)
         provider = sdc.get('data-provider')
         sdc = extract_attributes(sdc_el)
         provider = sdc.get('data-provider')
-        if provider == 'ooyala':
-            video_id = sdc['data-sdc-video-id']
-            video_url = 'ooyala:%s' % video_id
-            ie_key = 'Ooyala'
-            ooyala_el = self._search_regex(
-                r'(<div[^>]+class="[^"]*\bsdc-article-video__media-ooyala\b[^"]*"[^>]+data-video-id="%s"[^>]*>)' % video_id,
-                webpage, 'video data', fatal=False)
-            if ooyala_el:
-                ooyala_attrs = extract_attributes(ooyala_el) or {}
-                if ooyala_attrs.get('data-token-required') == 'true':
-                    token_fetch_url = (self._parse_json(ooyala_attrs.get(
-                        'data-token-fetch-options', '{}'),
-                        video_id, fatal=False) or {}).get('url')
-                    if token_fetch_url:
-                        embed_token = self._download_json(urljoin(
-                            url, token_fetch_url), video_id, fatal=False)
-                        if embed_token:
-                            video_url = smuggle_url(
-                                video_url, {'embed_token': embed_token})
-        elif provider == 'brightcove':
+        if provider == 'brightcove':
             video_id = sdc['data-video-id']
             account_id = sdc.get('data-account-id') or '6058004172001'
             player_id = sdc.get('data-player-id') or 'RC9PQUaJ6'
             video_id = sdc['data-video-id']
             account_id = sdc.get('data-account-id') or '6058004172001'
             player_id = sdc.get('data-player-id') or 'RC9PQUaJ6'
@@ -52,7 +31,7 @@ def _process_ooyala_element(self, webpage, sdc_el, url):
     def _real_extract(self, url):
         video_id = self._match_id(url)
         webpage = self._download_webpage(url, video_id)
     def _real_extract(self, url):
         video_id = self._match_id(url)
         webpage = self._download_webpage(url, video_id)
-        info = self._process_ooyala_element(webpage, self._search_regex(
+        info = self._process_video_element(webpage, self._search_regex(
             self._SDC_EL_REGEX, webpage, 'sdc element'), url)
         info.update({
             'title': self._og_search_title(webpage),
             self._SDC_EL_REGEX, webpage, 'sdc element'), url)
         info.update({
             'title': self._og_search_title(webpage),
@@ -73,7 +52,7 @@ class SkySportsIE(SkyBaseIE):
             'title': 'Bale: It\'s our time to shine',
             'description': 'md5:e88bda94ae15f7720c5cb467e777bb6d',
         },
             'title': 'Bale: It\'s our time to shine',
             'description': 'md5:e88bda94ae15f7720c5cb467e777bb6d',
         },
-        'add_ie': ['Ooyala'],
+        'add_ie': ['BrightcoveNew'],
     }, {
         'url': 'https://www.skysports.com/watch/video/sports/f1/12160544/abu-dhabi-gp-the-notebook',
         'only_matching': True,
     }, {
         'url': 'https://www.skysports.com/watch/video/sports/f1/12160544/abu-dhabi-gp-the-notebook',
         'only_matching': True,
@@ -122,7 +101,7 @@ def _real_extract(self, url):
         article_id = self._match_id(url)
         webpage = self._download_webpage(url, article_id)
 
         article_id = self._match_id(url)
         webpage = self._download_webpage(url, article_id)
 
-        entries = [self._process_ooyala_element(webpage, sdc_el, url)
+        entries = [self._process_video_element(webpage, sdc_el, url)
                    for sdc_el in re.findall(self._SDC_EL_REGEX, webpage)]
 
         return self.playlist_result(
                    for sdc_el in re.findall(self._SDC_EL_REGEX, webpage)]
 
         return self.playlist_result(
@@ -149,7 +128,7 @@ def _real_extract(self, url):
 
         entries = []
         for sdc_el in re.findall(self._SDC_EL_REGEX, webpage):
 
         entries = []
         for sdc_el in re.findall(self._SDC_EL_REGEX, webpage):
-            entries.append(self._process_ooyala_element(webpage, sdc_el, url))
+            entries.append(self._process_video_element(webpage, sdc_el, url))
 
         return self.playlist_result(
             entries, article_id, self._og_search_title(webpage),
 
         return self.playlist_result(
             entries, article_id, self._og_search_title(webpage),
diff --git a/yt_dlp/extractor/spankwire.py b/yt_dlp/extractor/spankwire.py
deleted file mode 100644 (file)
index 334b297..0000000
+++ /dev/null
@@ -1,174 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..utils import (
-    float_or_none,
-    int_or_none,
-    merge_dicts,
-    str_or_none,
-    str_to_int,
-    url_or_none,
-)
-
-
-class SpankwireIE(InfoExtractor):
-    _VALID_URL = r'''(?x)
-                    https?://
-                        (?:www\.)?spankwire\.com/
-                        (?:
-                            [^/]+/video|
-                            EmbedPlayer\.aspx/?\?.*?\bArticleId=
-                        )
-                        (?P<id>\d+)
-                    '''
-    _EMBED_REGEX = [r'<iframe[^>]+\bsrc=["\'](?P<url>(?:https?:)?//(?:www\.)?spankwire\.com/EmbedPlayer\.aspx/?\?.*?\bArticleId=\d+)']
-    _TESTS = [{
-        # download URL pattern: */<height>P_<tbr>K_<video_id>.mp4
-        'url': 'http://www.spankwire.com/Buckcherry-s-X-Rated-Music-Video-Crazy-Bitch/video103545/',
-        'md5': '5aa0e4feef20aad82cbcae3aed7ab7cd',
-        'info_dict': {
-            'id': '103545',
-            'ext': 'mp4',
-            'title': 'Buckcherry`s X Rated Music Video Crazy Bitch',
-            'description': 'Crazy Bitch X rated music video.',
-            'duration': 222,
-            'uploader': 'oreusz',
-            'uploader_id': '124697',
-            'timestamp': 1178587885,
-            'upload_date': '20070508',
-            'average_rating': float,
-            'view_count': int,
-            'comment_count': int,
-            'age_limit': 18,
-            'categories': list,
-            'tags': list,
-        },
-    }, {
-        # download URL pattern: */mp4_<format_id>_<video_id>.mp4
-        'url': 'http://www.spankwire.com/Titcums-Compiloation-I/video1921551/',
-        'md5': '09b3c20833308b736ae8902db2f8d7e6',
-        'info_dict': {
-            'id': '1921551',
-            'ext': 'mp4',
-            'title': 'Titcums Compiloation I',
-            'description': 'cum on tits',
-            'uploader': 'dannyh78999',
-            'uploader_id': '3056053',
-            'upload_date': '20150822',
-            'age_limit': 18,
-        },
-        'params': {
-            'proxy': '127.0.0.1:8118'
-        },
-        'skip': 'removed',
-    }, {
-        'url': 'https://www.spankwire.com/EmbedPlayer.aspx/?ArticleId=156156&autostart=true',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        video = self._download_json(
-            'https://www.spankwire.com/api/video/%s.json' % video_id, video_id)
-
-        title = video['title']
-
-        formats = []
-        videos = video.get('videos')
-        if isinstance(videos, dict):
-            for format_id, format_url in videos.items():
-                video_url = url_or_none(format_url)
-                if not format_url:
-                    continue
-                height = int_or_none(self._search_regex(
-                    r'(\d+)[pP]', format_id, 'height', default=None))
-                m = re.search(
-                    r'/(?P<height>\d+)[pP]_(?P<tbr>\d+)[kK]', video_url)
-                if m:
-                    tbr = int(m.group('tbr'))
-                    height = height or int(m.group('height'))
-                else:
-                    tbr = None
-                formats.append({
-                    'url': video_url,
-                    'format_id': '%dp' % height if height else format_id,
-                    'height': height,
-                    'tbr': tbr,
-                })
-        m3u8_url = url_or_none(video.get('HLS'))
-        if m3u8_url:
-            formats.extend(self._extract_m3u8_formats(
-                m3u8_url, video_id, 'mp4', entry_protocol='m3u8_native',
-                m3u8_id='hls', fatal=False))
-
-        view_count = str_to_int(video.get('viewed'))
-
-        thumbnails = []
-        for preference, t in enumerate(('', '2x'), start=0):
-            thumbnail_url = url_or_none(video.get('poster%s' % t))
-            if not thumbnail_url:
-                continue
-            thumbnails.append({
-                'url': thumbnail_url,
-                'preference': preference,
-            })
-
-        def extract_names(key):
-            entries_list = video.get(key)
-            if not isinstance(entries_list, list):
-                return
-            entries = []
-            for entry in entries_list:
-                name = str_or_none(entry.get('name'))
-                if name:
-                    entries.append(name)
-            return entries
-
-        categories = extract_names('categories')
-        tags = extract_names('tags')
-
-        uploader = None
-        info = {}
-
-        webpage = self._download_webpage(
-            'https://www.spankwire.com/_/video%s/' % video_id, video_id,
-            fatal=False)
-        if webpage:
-            info = self._search_json_ld(webpage, video_id, default={})
-            thumbnail_url = None
-            if 'thumbnail' in info:
-                thumbnail_url = url_or_none(info['thumbnail'])
-                del info['thumbnail']
-            if not thumbnail_url:
-                thumbnail_url = self._og_search_thumbnail(webpage)
-            if thumbnail_url:
-                thumbnails.append({
-                    'url': thumbnail_url,
-                    'preference': 10,
-                })
-            uploader = self._html_search_regex(
-                r'(?s)by\s*<a[^>]+\bclass=["\']uploaded__by[^>]*>(.+?)</a>',
-                webpage, 'uploader', fatal=False)
-            if not view_count:
-                view_count = str_to_int(self._search_regex(
-                    r'data-views=["\']([\d,.]+)', webpage, 'view count',
-                    fatal=False))
-
-        return merge_dicts({
-            'id': video_id,
-            'title': title,
-            'description': video.get('description'),
-            'duration': int_or_none(video.get('duration')),
-            'thumbnails': thumbnails,
-            'uploader': uploader,
-            'uploader_id': str_or_none(video.get('userId')),
-            'timestamp': int_or_none(video.get('time_approved_on')),
-            'average_rating': float_or_none(video.get('rating')),
-            'view_count': view_count,
-            'comment_count': int_or_none(video.get('comments')),
-            'age_limit': 18,
-            'categories': categories,
-            'tags': tags,
-            'formats': formats,
-        }, info)
index 3cc39870f9da7097ec22eccb811c37ff8a79db2f..f0b3b585ffd90bda505cd43848ffadc68dcb6e07 100644 (file)
@@ -6,6 +6,7 @@
 
 
 class SRMediathekIE(ARDMediathekBaseIE):
 
 
 class SRMediathekIE(ARDMediathekBaseIE):
+    _WORKING = False
     IE_NAME = 'sr:mediathek'
     IE_DESC = 'Saarländischer Rundfunk'
     _VALID_URL = r'https?://sr-mediathek(?:\.sr-online)?\.de/index\.php\?.*?&id=(?P<id>[0-9]+)'
     IE_NAME = 'sr:mediathek'
     IE_DESC = 'Saarländischer Rundfunk'
     _VALID_URL = r'https?://sr-mediathek(?:\.sr-online)?\.de/index\.php\?.*?&id=(?P<id>[0-9]+)'
diff --git a/yt_dlp/extractor/streamcloud.py b/yt_dlp/extractor/streamcloud.py
deleted file mode 100644 (file)
index 7289809..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..utils import (
-    ExtractorError,
-    urlencode_postdata,
-)
-
-
-class StreamcloudIE(InfoExtractor):
-    IE_NAME = 'streamcloud.eu'
-    _VALID_URL = r'https?://streamcloud\.eu/(?P<id>[a-zA-Z0-9_-]+)(?:/(?P<fname>[^#?]*)\.html)?'
-
-    _TESTS = [{
-        'url': 'http://streamcloud.eu/skp9j99s4bpz/youtube-dl_test_video_____________-BaW_jenozKc.mp4.html',
-        'md5': '6bea4c7fa5daaacc2a946b7146286686',
-        'info_dict': {
-            'id': 'skp9j99s4bpz',
-            'ext': 'mp4',
-            'title': 'youtube-dl test video  \'/\\ ä ↭',
-        },
-        'skip': 'Only available from the EU'
-    }, {
-        'url': 'http://streamcloud.eu/ua8cmfh1nbe6/NSHIP-148--KUC-NG--H264-.mp4.html',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        url = 'http://streamcloud.eu/%s' % video_id
-
-        orig_webpage = self._download_webpage(url, video_id)
-
-        if '>File Not Found<' in orig_webpage:
-            raise ExtractorError(
-                'Video %s does not exist' % video_id, expected=True)
-
-        fields = re.findall(r'''(?x)<input\s+
-            type="(?:hidden|submit)"\s+
-            name="([^"]+)"\s+
-            (?:id="[^"]+"\s+)?
-            value="([^"]*)"
-            ''', orig_webpage)
-
-        self._sleep(6, video_id)
-
-        webpage = self._download_webpage(
-            url, video_id, data=urlencode_postdata(fields), headers={
-                b'Content-Type': b'application/x-www-form-urlencoded',
-            })
-
-        try:
-            title = self._html_search_regex(
-                r'<h1[^>]*>([^<]+)<', webpage, 'title')
-            video_url = self._search_regex(
-                r'file:\s*"([^"]+)"', webpage, 'video URL')
-        except ExtractorError:
-            message = self._html_search_regex(
-                r'(?s)<div[^>]+class=(["\']).*?msgboxinfo.*?\1[^>]*>(?P<message>.+?)</div>',
-                webpage, 'message', default=None, group='message')
-            if message:
-                raise ExtractorError('%s said: %s' % (self.IE_NAME, message), expected=True)
-            raise
-        thumbnail = self._search_regex(
-            r'image:\s*"([^"]+)"', webpage, 'thumbnail URL', fatal=False)
-
-        return {
-            'id': video_id,
-            'title': title,
-            'url': video_url,
-            'thumbnail': thumbnail,
-            'http_headers': {
-                'Referer': url,
-            },
-        }
diff --git a/yt_dlp/extractor/swrmediathek.py b/yt_dlp/extractor/swrmediathek.py
deleted file mode 100644 (file)
index 38bdfce..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    parse_duration,
-    int_or_none,
-    determine_protocol,
-)
-
-
-class SWRMediathekIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?swrmediathek\.de/(?:content/)?player\.htm\?show=(?P<id>[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12})'
-
-    _TESTS = [{
-        'url': 'http://swrmediathek.de/player.htm?show=849790d0-dab8-11e3-a953-0026b975f2e6',
-        'md5': '8c5f6f0172753368547ca8413a7768ac',
-        'info_dict': {
-            'id': '849790d0-dab8-11e3-a953-0026b975f2e6',
-            'ext': 'mp4',
-            'title': 'SWR odysso',
-            'description': 'md5:2012e31baad36162e97ce9eb3f157b8a',
-            'thumbnail': r're:^http:.*\.jpg$',
-            'duration': 2602,
-            'upload_date': '20140515',
-            'uploader': 'SWR Fernsehen',
-            'uploader_id': '990030',
-        },
-    }, {
-        'url': 'http://swrmediathek.de/player.htm?show=0e1a8510-ddf2-11e3-9be3-0026b975f2e6',
-        'md5': 'b10ab854f912eecc5a6b55cd6fc1f545',
-        'info_dict': {
-            'id': '0e1a8510-ddf2-11e3-9be3-0026b975f2e6',
-            'ext': 'mp4',
-            'title': 'Nachtcafé - Alltagsdroge Alkohol - zwischen Sektempfang und Komasaufen',
-            'description': 'md5:e0a3adc17e47db2c23aab9ebc36dbee2',
-            'thumbnail': r're:http://.*\.jpg',
-            'duration': 5305,
-            'upload_date': '20140516',
-            'uploader': 'SWR Fernsehen',
-            'uploader_id': '990030',
-        },
-        'skip': 'redirect to http://swrmediathek.de/index.htm?hinweis=swrlink',
-    }, {
-        'url': 'http://swrmediathek.de/player.htm?show=bba23e10-cb93-11e3-bf7f-0026b975f2e6',
-        'md5': '4382e4ef2c9d7ce6852535fa867a0dd3',
-        'info_dict': {
-            'id': 'bba23e10-cb93-11e3-bf7f-0026b975f2e6',
-            'ext': 'mp3',
-            'title': 'Saša Stanišic: Vor dem Fest',
-            'description': 'md5:5b792387dc3fbb171eb709060654e8c9',
-            'thumbnail': r're:http://.*\.jpg',
-            'duration': 3366,
-            'upload_date': '20140520',
-            'uploader': 'SWR 2',
-            'uploader_id': '284670',
-        },
-        'skip': 'redirect to http://swrmediathek.de/index.htm?hinweis=swrlink',
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        video = self._download_json(
-            'http://swrmediathek.de/AjaxEntry?ekey=%s' % video_id,
-            video_id, 'Downloading video JSON')
-
-        attr = video['attr']
-        title = attr['entry_title']
-        media_type = attr.get('entry_etype')
-
-        formats = []
-        for entry in video.get('sub', []):
-            if entry.get('name') != 'entry_media':
-                continue
-
-            entry_attr = entry.get('attr', {})
-            f_url = entry_attr.get('val2')
-            if not f_url:
-                continue
-            codec = entry_attr.get('val0')
-            if codec == 'm3u8':
-                formats.extend(self._extract_m3u8_formats(
-                    f_url, video_id, 'mp4', 'm3u8_native',
-                    m3u8_id='hls', fatal=False))
-            elif codec == 'f4m':
-                formats.extend(self._extract_f4m_formats(
-                    f_url + '?hdcore=3.7.0', video_id,
-                    f4m_id='hds', fatal=False))
-            else:
-                formats.append({
-                    'format_id': determine_protocol({'url': f_url}),
-                    'url': f_url,
-                    'quality': int_or_none(entry_attr.get('val1')),
-                    'vcodec': codec if media_type == 'Video' else 'none',
-                    'acodec': codec if media_type == 'Audio' else None,
-                })
-
-        upload_date = None
-        entry_pdatet = attr.get('entry_pdatet')
-        if entry_pdatet:
-            upload_date = entry_pdatet[:-4]
-
-        return {
-            'id': video_id,
-            'title': title,
-            'description': attr.get('entry_descl'),
-            'thumbnail': attr.get('entry_image_16_9'),
-            'duration': parse_duration(attr.get('entry_durat')),
-            'upload_date': upload_date,
-            'uploader': attr.get('channel_title'),
-            'uploader_id': attr.get('channel_idkey'),
-            'formats': formats,
-        }
diff --git a/yt_dlp/extractor/techtalks.py b/yt_dlp/extractor/techtalks.py
deleted file mode 100644 (file)
index d37de36..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..utils import (
-    get_element_by_attribute,
-    clean_html,
-)
-
-
-class TechTalksIE(InfoExtractor):
-    _VALID_URL = r'https?://techtalks\.tv/talks/(?:[^/]+/)?(?P<id>\d+)'
-
-    _TESTS = [{
-        'url': 'http://techtalks.tv/talks/learning-topic-models-going-beyond-svd/57758/',
-        'info_dict': {
-            'id': '57758',
-            'title': 'Learning Topic Models --- Going beyond SVD',
-        },
-        'playlist': [
-            {
-                'info_dict': {
-                    'id': '57758',
-                    'ext': 'flv',
-                    'title': 'Learning Topic Models --- Going beyond SVD',
-                },
-            },
-            {
-                'info_dict': {
-                    'id': '57758-slides',
-                    'ext': 'flv',
-                    'title': 'Learning Topic Models --- Going beyond SVD',
-                },
-            },
-        ],
-        'params': {
-            # rtmp download
-            'skip_download': True,
-        },
-    }, {
-        'url': 'http://techtalks.tv/talks/57758',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        mobj = self._match_valid_url(url)
-        talk_id = mobj.group('id')
-        webpage = self._download_webpage(url, talk_id)
-        rtmp_url = self._search_regex(
-            r'netConnectionUrl: \'(.*?)\'', webpage, 'rtmp url')
-        play_path = self._search_regex(
-            r'href=\'(.*?)\' [^>]*id="flowplayer_presenter"',
-            webpage, 'presenter play path')
-        title = clean_html(get_element_by_attribute('class', 'title', webpage))
-        video_info = {
-            'id': talk_id,
-            'title': title,
-            'url': rtmp_url,
-            'play_path': play_path,
-            'ext': 'flv',
-        }
-        m_slides = re.search(r'<a class="slides" href=\'(.*?)\'', webpage)
-        if m_slides is None:
-            return video_info
-        else:
-            return {
-                '_type': 'playlist',
-                'id': talk_id,
-                'title': title,
-                'entries': [
-                    video_info,
-                    # The slides video
-                    {
-                        'id': talk_id + '-slides',
-                        'title': title,
-                        'url': rtmp_url,
-                        'play_path': m_slides.group(1),
-                        'ext': 'flv',
-                    },
-                ],
-            }
index 20bb824208776c14e47fb47eeb8872a813979645..a3f0c7cda878195ae5e0adabc8b7d9ac5e7344bd 100644 (file)
@@ -77,7 +77,6 @@ class TelecincoIE(InfoExtractor):
         'url': 'http://www.telecinco.es/espanasinirmaslejos/Espana-gran-destino-turistico_2_1240605043.html',
         'only_matching': True,
     }, {
         'url': 'http://www.telecinco.es/espanasinirmaslejos/Espana-gran-destino-turistico_2_1240605043.html',
         'only_matching': True,
     }, {
-        # ooyala video
         'url': 'http://www.cuatro.com/chesterinlove/a-carta/chester-chester_in_love-chester_edu_2_2331030022.html',
         'only_matching': True,
     }]
         'url': 'http://www.cuatro.com/chesterinlove/a-carta/chester-chester_in_love-chester_edu_2_2331030022.html',
         'only_matching': True,
     }]
diff --git a/yt_dlp/extractor/tinypic.py b/yt_dlp/extractor/tinypic.py
deleted file mode 100644 (file)
index 216208c..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..utils import ExtractorError
-
-
-class TinyPicIE(InfoExtractor):
-    IE_NAME = 'tinypic'
-    IE_DESC = 'tinypic.com videos'
-    _VALID_URL = r'https?://(?:.+?\.)?tinypic\.com/player\.php\?v=(?P<id>[^&]+)&s=\d+'
-
-    _TESTS = [
-        {
-            'url': 'http://tinypic.com/player.php?v=6xw7tc%3E&s=5#.UtqZmbRFCM8',
-            'md5': '609b74432465364e72727ebc6203f044',
-            'info_dict': {
-                'id': '6xw7tc',
-                'ext': 'flv',
-                'title': 'shadow phenomenon weird',
-            },
-        },
-        {
-            'url': 'http://de.tinypic.com/player.php?v=dy90yh&s=8',
-            'only_matching': True,
-        }
-    ]
-
-    def _real_extract(self, url):
-        mobj = self._match_valid_url(url)
-        video_id = mobj.group('id')
-
-        webpage = self._download_webpage(url, video_id, 'Downloading page')
-
-        mobj = re.search(r'(?m)fo\.addVariable\("file",\s"(?P<fileid>[\da-z]+)"\);\n'
-                         r'\s+fo\.addVariable\("s",\s"(?P<serverid>\d+)"\);', webpage)
-        if mobj is None:
-            raise ExtractorError('Video %s does not exist' % video_id, expected=True)
-
-        file_id = mobj.group('fileid')
-        server_id = mobj.group('serverid')
-
-        KEYWORDS_SUFFIX = ', Video, images, photos, videos, myspace, ebay, video hosting, photo hosting'
-        keywords = self._html_search_meta('keywords', webpage, 'title')
-        title = keywords[:-len(KEYWORDS_SUFFIX)] if keywords.endswith(KEYWORDS_SUFFIX) else ''
-
-        video_url = 'http://v%s.tinypic.com/%s.flv' % (server_id, file_id)
-        thumbnail = 'http://v%s.tinypic.com/%s_th.jpg' % (server_id, file_id)
-
-        return {
-            'id': file_id,
-            'url': video_url,
-            'thumbnail': thumbnail,
-            'title': title
-        }
diff --git a/yt_dlp/extractor/tokentube.py b/yt_dlp/extractor/tokentube.py
deleted file mode 100644 (file)
index d022e27..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-import functools
-import re
-
-from .common import InfoExtractor
-from ..utils import (
-    clean_html,
-    get_element_by_class,
-    parse_count,
-    remove_end,
-    unified_strdate,
-    js_to_json,
-    OnDemandPagedList,
-)
-
-
-class TokentubeIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?tokentube\.net/(?:view\?[vl]=|[vl]/)(?P<id>\d+)'
-    _TESTS = [{
-        'url': 'https://tokentube.net/l/3236632011/Praise-A-Thon-Pastori-Chrisin-ja-Pastori-Bennyn-kanssa-27-8-2021',
-        'info_dict': {
-            'id': '3236632011',
-            'ext': 'mp4',
-            'title': 'Praise-A-Thon Pastori Chrisin ja Pastori Bennyn kanssa 27.8.2021',
-            'description': '',
-            'uploader': 'Pastori Chris - Rapsodia.fi',
-            'upload_date': '20210827',
-        },
-        'params': {
-            'skip_download': True,
-        },
-    }, {
-        'url': 'https://tokentube.net/v/3950239124/Linux-Ubuntu-Studio-perus-k%C3%A4ytt%C3%B6',
-        'md5': '0e1f00421f501f5eada9890d38fcfb56',
-        'info_dict': {
-            'id': '3950239124',
-            'ext': 'mp4',
-            'title': 'Linux Ubuntu Studio perus käyttö',
-            'description': 'md5:46077d0daaba1974f2dc381257f9d64c',
-            'uploader': 'jyrilehtonen',
-            'upload_date': '20210825',
-        },
-    }, {
-        'url': 'https://tokentube.net/view?v=3582463289',
-        'info_dict': {
-            'id': '3582463289',
-            'ext': 'mp4',
-            'title': 'Police for Freedom - toiminta aloitetaan Suomessa ❤️??',
-            'description': 'md5:37ebf1cb44264e0bf23ed98b337ee63e',
-            'uploader': 'Voitontie',
-            'upload_date': '20210428',
-        }
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-
-        title = self._html_search_regex(r'<h1\s*class=["\']title-text["\']>(.+?)</h1>', webpage, 'title')
-
-        data_json = self._html_search_regex(r'({["\']html5["\'].+?}}}+)', webpage, 'data json')
-        data_json = self._parse_json(js_to_json(data_json), video_id, fatal=False)
-
-        sources = data_json.get('sources') or self._parse_json(
-            self._html_search_regex(r'updateSrc\(([^\)]+)\)', webpage, 'sources'),
-            video_id, transform_source=js_to_json)
-
-        formats = [{
-            'url': format.get('src'),
-            'format_id': format.get('label'),
-            'height': format.get('res'),
-        } for format in sources]
-
-        view_count = parse_count(self._html_search_regex(
-            r'<p\s*class=["\']views_counter["\']>\s*([\d\.,]+)\s*<span>views?</span></p>',
-            webpage, 'view_count', fatal=False))
-
-        like_count = parse_count(self._html_search_regex(
-            r'<div\s*class="sh_button\s*likes_count">\s*(\d+)\s*</div>',
-            webpage, 'like count', fatal=False))
-
-        dislike_count = parse_count(self._html_search_regex(
-            r'<div\s*class="sh_button\s*dislikes_count">\s*(\d+)\s*</div>',
-            webpage, 'dislike count', fatal=False))
-
-        upload_date = unified_strdate(self._html_search_regex(
-            r'<span\s*class="p-date">Published\s*on\s+([^<]+)',
-            webpage, 'upload date', fatal=False))
-
-        uploader = self._html_search_regex(
-            r'<a\s*class="place-left"[^>]+>(.+?)</a>',
-            webpage, 'uploader', fatal=False)
-
-        description = (clean_html(get_element_by_class('p-d-txt', webpage))
-                       or self._html_search_meta(('og:description', 'description', 'twitter:description'), webpage))
-
-        description = remove_end(description, 'Category')
-
-        return {
-            'id': video_id,
-            'formats': formats,
-            'title': title,
-            'view_count': view_count,
-            'like_count': like_count,
-            'dislike_count': dislike_count,
-            'upload_date': upload_date,
-            'description': description,
-            'uploader': uploader,
-        }
-
-
-class TokentubeChannelIE(InfoExtractor):
-    _PAGE_SIZE = 20
-    IE_NAME = 'Tokentube:channel'
-    _VALID_URL = r'https?://(?:www\.)?tokentube\.net/channel/(?P<id>\d+)/[^/]+(?:/videos)?'
-    _TESTS = [{
-        'url': 'https://tokentube.net/channel/3697658904/TokenTube',
-        'info_dict': {
-            'id': '3697658904',
-        },
-        'playlist_mincount': 7,
-    }, {
-        'url': 'https://tokentube.net/channel/3353234420/Linux/videos',
-        'info_dict': {
-            'id': '3353234420',
-        },
-        'playlist_mincount': 20,
-    }, {
-        'url': 'https://tokentube.net/channel/3475834195/Voitontie',
-        'info_dict': {
-            'id': '3475834195',
-        },
-        'playlist_mincount': 150,
-    }]
-
-    def _fetch_page(self, channel_id, page):
-        page += 1
-        videos_info = self._download_webpage(
-            f'https://tokentube.net/videos?p=0&m=1&sort=recent&u={channel_id}&page={page}',
-            channel_id, headers={'X-Requested-With': 'XMLHttpRequest'},
-            note=f'Downloading page {page}', fatal=False)
-        if '</i> Sorry, no results were found.' not in videos_info:
-            for path, media_id in re.findall(
-                    r'<a[^>]+\bhref=["\']([^"\']+/[lv]/(\d+)/\S+)["\'][^>]+>',
-                    videos_info):
-                yield self.url_result(path, ie=TokentubeIE.ie_key(), video_id=media_id)
-
-    def _real_extract(self, url):
-        channel_id = self._match_id(url)
-
-        entries = OnDemandPagedList(functools.partial(
-            self._fetch_page, channel_id), self._PAGE_SIZE)
-
-        return self.playlist_result(entries, channel_id)
index bc733618614109131e12bdf093f96e4ea14ea660..aa7ee6c489e78b7c75c9d197456698c9ebb3a3b3 100644 (file)
@@ -3,6 +3,7 @@
 
 
 class ToypicsIE(InfoExtractor):
 
 
 class ToypicsIE(InfoExtractor):
+    _WORKING = False
     IE_DESC = 'Toypics video'
     _VALID_URL = r'https?://videos\.toypics\.net/view/(?P<id>[0-9]+)'
     _TEST = {
     IE_DESC = 'Toypics video'
     _VALID_URL = r'https?://videos\.toypics\.net/view/(?P<id>[0-9]+)'
     _TEST = {
@@ -43,6 +44,7 @@ def _real_extract(self, url):
 
 
 class ToypicsUserIE(InfoExtractor):
 
 
 class ToypicsUserIE(InfoExtractor):
+    _WORKING = False
     IE_DESC = 'Toypics user profile'
     _VALID_URL = r'https?://videos\.toypics\.net/(?!view)(?P<id>[^/?#&]+)'
     _TEST = {
     IE_DESC = 'Toypics user profile'
     _VALID_URL = r'https?://videos\.toypics\.net/(?!view)(?P<id>[^/?#&]+)'
     _TEST = {
diff --git a/yt_dlp/extractor/trilulilu.py b/yt_dlp/extractor/trilulilu.py
deleted file mode 100644 (file)
index fb97be7..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    ExtractorError,
-    int_or_none,
-    parse_iso8601,
-)
-
-
-class TriluliluIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:(?:www|m)\.)?trilulilu\.ro/(?:[^/]+/)?(?P<id>[^/#\?]+)'
-    _TESTS = [{
-        'url': 'http://www.trilulilu.ro/big-buck-bunny-1',
-        'md5': '68da087b676a6196a413549212f60cc6',
-        'info_dict': {
-            'id': 'ae2899e124140b',
-            'ext': 'mp4',
-            'title': 'Big Buck Bunny',
-            'description': ':) pentru copilul din noi',
-            'uploader_id': 'chipy',
-            'upload_date': '20120304',
-            'timestamp': 1330830647,
-            'uploader': 'chipy',
-            'view_count': int,
-            'like_count': int,
-            'comment_count': int,
-        },
-    }, {
-        'url': 'http://www.trilulilu.ro/adena-ft-morreti-inocenta',
-        'md5': '929dfb8729dc71750463af88bbbbf4a4',
-        'info_dict': {
-            'id': 'f299710e3c91c5',
-            'ext': 'mp4',
-            'title': 'Adena ft. Morreti - Inocenta',
-            'description': 'pop music',
-            'uploader_id': 'VEVOmixt',
-            'upload_date': '20151204',
-            'uploader': 'VEVOmixt',
-            'timestamp': 1449187937,
-            'view_count': int,
-            'like_count': int,
-            'comment_count': int,
-        },
-    }]
-
-    def _real_extract(self, url):
-        display_id = self._match_id(url)
-        media_info = self._download_json('http://m.trilulilu.ro/%s?format=json' % display_id, display_id)
-
-        age_limit = 0
-        errors = media_info.get('errors', {})
-        if errors.get('friends'):
-            raise ExtractorError('This video is private.', expected=True)
-        elif errors.get('geoblock'):
-            raise ExtractorError('This video is not available in your country.', expected=True)
-        elif errors.get('xxx_unlogged'):
-            age_limit = 18
-
-        media_class = media_info.get('class')
-        if media_class not in ('video', 'audio'):
-            raise ExtractorError('not a video or an audio')
-
-        user = media_info.get('user', {})
-
-        thumbnail = media_info.get('cover_url')
-        if thumbnail:
-            thumbnail.format(width='1600', height='1200')
-
-        # TODO: get correct ext for audio files
-        stream_type = media_info.get('stream_type')
-        formats = [{
-            'url': media_info['href'],
-            'ext': stream_type,
-        }]
-        if media_info.get('is_hd'):
-            formats.append({
-                'format_id': 'hd',
-                'url': media_info['hrefhd'],
-                'ext': stream_type,
-            })
-        if media_class == 'audio':
-            formats[0]['vcodec'] = 'none'
-        else:
-            formats[0]['format_id'] = 'sd'
-
-        return {
-            'id': media_info['identifier'].split('|')[1],
-            'display_id': display_id,
-            'formats': formats,
-            'title': media_info['title'],
-            'description': media_info.get('description'),
-            'thumbnail': thumbnail,
-            'uploader_id': user.get('username'),
-            'uploader': user.get('fullname'),
-            'timestamp': parse_iso8601(media_info.get('published'), ' '),
-            'duration': int_or_none(media_info.get('duration')),
-            'view_count': int_or_none(media_info.get('count_views')),
-            'like_count': int_or_none(media_info.get('count_likes')),
-            'comment_count': int_or_none(media_info.get('count_comments')),
-            'age_limit': age_limit,
-        }
index 77ed05ffdadd1b1dbf7c1d1cf2474fbcaffb44e7..5f15b4581e3d19285305a62649fb397994ad92c4 100644 (file)
@@ -1,13 +1,20 @@
 import re
 
 import re
 
+from .common import InfoExtractor
+from ..aes import aes_decrypt_text
+from ..compat import compat_urllib_parse_unquote
 from ..utils import (
 from ..utils import (
+    determine_ext,
+    format_field,
     int_or_none,
     str_to_int,
     int_or_none,
     str_to_int,
+    strip_or_none,
+    url_or_none,
 )
 )
-from .keezmovies import KeezMoviesIE
 
 
 
 
-class Tube8IE(KeezMoviesIE):  # XXX: Do not subclass from concrete IE
+class Tube8IE(InfoExtractor):
+    _WORKING = False
     _VALID_URL = r'https?://(?:www\.)?tube8\.com/(?:[^/]+/)+(?P<display_id>[^/]+)/(?P<id>\d+)'
     _EMBED_REGEX = [r'<iframe[^>]+\bsrc=["\'](?P<url>(?:https?:)?//(?:www\.)?tube8\.com/embed/(?:[^/]+/)+\d+)']
     _TESTS = [{
     _VALID_URL = r'https?://(?:www\.)?tube8\.com/(?:[^/]+/)+(?P<display_id>[^/]+)/(?P<id>\d+)'
     _EMBED_REGEX = [r'<iframe[^>]+\bsrc=["\'](?P<url>(?:https?:)?//(?:www\.)?tube8\.com/embed/(?:[^/]+/)+\d+)']
     _TESTS = [{
@@ -30,6 +37,90 @@ class Tube8IE(KeezMoviesIE):  # XXX: Do not subclass from concrete IE
         'only_matching': True,
     }]
 
         'only_matching': True,
     }]
 
+    def _extract_info(self, url, fatal=True):
+        mobj = self._match_valid_url(url)
+        video_id = mobj.group('id')
+        display_id = (mobj.group('display_id')
+                      if 'display_id' in mobj.groupdict()
+                      else None) or mobj.group('id')
+
+        webpage = self._download_webpage(
+            url, display_id, headers={'Cookie': 'age_verified=1'})
+
+        formats = []
+        format_urls = set()
+
+        title = None
+        thumbnail = None
+        duration = None
+        encrypted = False
+
+        def extract_format(format_url, height=None):
+            format_url = url_or_none(format_url)
+            if not format_url or not format_url.startswith(('http', '//')):
+                return
+            if format_url in format_urls:
+                return
+            format_urls.add(format_url)
+            tbr = int_or_none(self._search_regex(
+                r'[/_](\d+)[kK][/_]', format_url, 'tbr', default=None))
+            if not height:
+                height = int_or_none(self._search_regex(
+                    r'[/_](\d+)[pP][/_]', format_url, 'height', default=None))
+            if encrypted:
+                format_url = aes_decrypt_text(
+                    video_url, title, 32).decode('utf-8')
+            formats.append({
+                'url': format_url,
+                'format_id': format_field(height, None, '%dp'),
+                'height': height,
+                'tbr': tbr,
+            })
+
+        flashvars = self._parse_json(
+            self._search_regex(
+                r'flashvars\s*=\s*({.+?});', webpage,
+                'flashvars', default='{}'),
+            display_id, fatal=False)
+
+        if flashvars:
+            title = flashvars.get('video_title')
+            thumbnail = flashvars.get('image_url')
+            duration = int_or_none(flashvars.get('video_duration'))
+            encrypted = flashvars.get('encrypted') is True
+            for key, value in flashvars.items():
+                mobj = re.search(r'quality_(\d+)[pP]', key)
+                if mobj:
+                    extract_format(value, int(mobj.group(1)))
+            video_url = flashvars.get('video_url')
+            if video_url and determine_ext(video_url, None):
+                extract_format(video_url)
+
+        video_url = self._html_search_regex(
+            r'flashvars\.video_url\s*=\s*(["\'])(?P<url>http.+?)\1',
+            webpage, 'video url', default=None, group='url')
+        if video_url:
+            extract_format(compat_urllib_parse_unquote(video_url))
+
+        if not formats:
+            if 'title="This video is no longer available"' in webpage:
+                self.raise_no_formats(
+                    'Video %s is no longer available' % video_id, expected=True)
+
+        if not title:
+            title = self._html_search_regex(
+                r'<h1[^>]*>([^<]+)', webpage, 'title')
+
+        return webpage, {
+            'id': video_id,
+            'display_id': display_id,
+            'title': strip_or_none(title),
+            'thumbnail': thumbnail,
+            'duration': duration,
+            'age_limit': 18,
+            'formats': formats,
+        }
+
     def _real_extract(self, url):
         webpage, info = self._extract_info(url)
 
     def _real_extract(self, url):
         webpage, info = self._extract_info(url)
 
diff --git a/yt_dlp/extractor/tunepk.py b/yt_dlp/extractor/tunepk.py
deleted file mode 100644 (file)
index e4e507b..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-from .common import InfoExtractor
-from ..compat import compat_str
-from ..utils import (
-    int_or_none,
-    try_get,
-    unified_timestamp,
-)
-
-
-class TunePkIE(InfoExtractor):
-    _VALID_URL = r'''(?x)
-                    https?://
-                        (?:
-                            (?:www\.)?tune\.pk/(?:video/|player/embed_player.php?.*?\bvid=)|
-                            embed\.tune\.pk/play/
-                        )
-                        (?P<id>\d+)
-                    '''
-    _TESTS = [{
-        'url': 'https://tune.pk/video/6919541/maudie-2017-international-trailer-1-ft-ethan-hawke-sally-hawkins',
-        'md5': '0c537163b7f6f97da3c5dd1e3ef6dd55',
-        'info_dict': {
-            'id': '6919541',
-            'ext': 'mp4',
-            'title': 'Maudie (2017) | International Trailer # 1 ft Ethan Hawke, Sally Hawkins',
-            'description': 'md5:eb5a04114fafef5cec90799a93a2d09c',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'timestamp': 1487327564,
-            'upload_date': '20170217',
-            'uploader': 'Movie Trailers',
-            'duration': 107,
-            'view_count': int,
-        }
-    }, {
-        'url': 'https://tune.pk/player/embed_player.php?vid=6919541&folder=2017/02/17/&width=600&height=350&autoplay=no',
-        'only_matching': True,
-    }, {
-        'url': 'https://embed.tune.pk/play/6919541?autoplay=no&ssl=yes&inline=true',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        webpage = self._download_webpage(
-            'https://tune.pk/video/%s' % video_id, video_id)
-
-        details = self._parse_json(
-            self._search_regex(
-                r'new\s+TunePlayer\(({.+?})\)\s*;\s*\n', webpage, 'tune player'),
-            video_id)['details']
-
-        video = details['video']
-        title = video.get('title') or self._og_search_title(
-            webpage, default=None) or self._html_search_meta(
-            'title', webpage, 'title', fatal=True)
-
-        formats = self._parse_jwplayer_formats(
-            details['player']['sources'], video_id)
-
-        description = self._og_search_description(
-            webpage, default=None) or self._html_search_meta(
-            'description', webpage, 'description')
-
-        thumbnail = video.get('thumb') or self._og_search_thumbnail(
-            webpage, default=None) or self._html_search_meta(
-            'thumbnail', webpage, 'thumbnail')
-
-        timestamp = unified_timestamp(video.get('date_added'))
-        uploader = try_get(
-            video, lambda x: x['uploader']['name'],
-            compat_str) or self._html_search_meta('author', webpage, 'author')
-
-        duration = int_or_none(video.get('duration'))
-        view_count = int_or_none(video.get('views'))
-
-        return {
-            'id': video_id,
-            'title': title,
-            'description': description,
-            'thumbnail': thumbnail,
-            'timestamp': timestamp,
-            'uploader': uploader,
-            'duration': duration,
-            'view_count': view_count,
-            'formats': formats,
-        }
diff --git a/yt_dlp/extractor/tvnet.py b/yt_dlp/extractor/tvnet.py
deleted file mode 100644 (file)
index 77426f7..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..utils import (
-    int_or_none,
-    unescapeHTML,
-    url_or_none,
-)
-
-
-class TVNetIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:[^/]+)\.tvnet\.gov\.vn/[^/]+/(?:\d+/)?(?P<id>\d+)(?:/|$)'
-    _TESTS = [{
-        # video
-        'url': 'http://de.tvnet.gov.vn/video/109788/vtv1---bac-tuyet-tai-lao-cai-va-ha-giang/tin-nong-24h',
-        'md5': 'b4d7abe0252c9b47774760b7519c7558',
-        'info_dict': {
-            'id': '109788',
-            'ext': 'mp4',
-            'title': 'VTV1 - Bắc tuyết tại Lào Cai và Hà Giang',
-            'thumbnail': r're:(?i)https?://.*\.(?:jpg|png)',
-            'is_live': False,
-            'view_count': int,
-        },
-    }, {
-        # audio
-        'url': 'http://vn.tvnet.gov.vn/radio/27017/vov1---ban-tin-chieu-10062018/doi-song-va-xa-hoi',
-        'md5': 'b5875ce9b0a2eecde029216d0e6db2ae',
-        'info_dict': {
-            'id': '27017',
-            'ext': 'm4a',
-            'title': 'VOV1 - Bản tin chiều (10/06/2018)',
-            'thumbnail': r're:(?i)https?://.*\.(?:jpg|png)',
-            'is_live': False,
-        },
-    }, {
-        'url': 'http://us.tvnet.gov.vn/video/118023/129999/ngay-0705',
-        'info_dict': {
-            'id': '129999',
-            'ext': 'mp4',
-            'title': 'VTV1 - Quốc hội với cử tri (11/06/2018)',
-            'thumbnail': r're:(?i)https?://.*\.(?:jpg|png)',
-            'is_live': False,
-        },
-        'params': {
-            'skip_download': True,
-        },
-    }, {
-        # live stream
-        'url': 'http://us.tvnet.gov.vn/kenh-truyen-hinh/1011/vtv1',
-        'info_dict': {
-            'id': '1011',
-            'ext': 'mp4',
-            'title': r're:^VTV1 \| LiveTV [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$',
-            'thumbnail': r're:(?i)https?://.*\.(?:jpg|png)',
-            'is_live': True,
-        },
-        'params': {
-            'skip_download': True,
-        },
-    }, {
-        # radio live stream
-        'url': 'http://vn.tvnet.gov.vn/kenh-truyen-hinh/1014',
-        'info_dict': {
-            'id': '1014',
-            'ext': 'm4a',
-            'title': r're:VOV1 \| LiveTV [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$',
-            'thumbnail': r're:(?i)https?://.*\.(?:jpg|png)',
-            'is_live': True,
-        },
-        'params': {
-            'skip_download': True,
-        },
-    }, {
-        'url': 'http://us.tvnet.gov.vn/phim/6136/25510/vtv3---ca-mot-doi-an-oan-tap-1-50/phim-truyen-hinh',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        webpage = self._download_webpage(url, video_id)
-
-        title = self._og_search_title(
-            webpage, default=None) or self._html_search_meta(
-            'title', webpage, default=None) or self._search_regex(
-            r'<title>([^<]+)<', webpage, 'title')
-        title = re.sub(r'\s*-\s*TV Net\s*$', '', title)
-
-        if '/video/' in url or '/radio/' in url:
-            is_live = False
-        elif '/kenh-truyen-hinh/' in url:
-            is_live = True
-        else:
-            is_live = None
-
-        data_file = unescapeHTML(self._search_regex(
-            r'data-file=(["\'])(?P<url>(?:https?:)?//.+?)\1', webpage,
-            'data file', group='url'))
-
-        stream_urls = set()
-        formats = []
-        for stream in self._download_json(data_file, video_id):
-            if not isinstance(stream, dict):
-                continue
-            stream_url = url_or_none(stream.get('url'))
-            if stream_url in stream_urls or not stream_url:
-                continue
-            stream_urls.add(stream_url)
-            formats.extend(self._extract_m3u8_formats(
-                stream_url, video_id, 'mp4', live=is_live, m3u8_id='hls', fatal=False))
-
-        # better support for radio streams
-        if title.startswith('VOV'):
-            for f in formats:
-                f.update({
-                    'ext': 'm4a',
-                    'vcodec': 'none',
-                })
-
-        thumbnail = self._og_search_thumbnail(
-            webpage, default=None) or unescapeHTML(
-            self._search_regex(
-                r'data-image=(["\'])(?P<url>(?:https?:)?//.+?)\1', webpage,
-                'thumbnail', default=None, group='url'))
-
-        view_count = int_or_none(self._search_regex(
-            r'(?s)<div[^>]+\bclass=["\'].*?view-count[^>]+>.*?(\d+).*?</div>',
-            webpage, 'view count', default=None))
-
-        return {
-            'id': video_id,
-            'title': title,
-            'thumbnail': thumbnail,
-            'is_live': is_live,
-            'view_count': view_count,
-            'formats': formats,
-        }
diff --git a/yt_dlp/extractor/tvnow.py b/yt_dlp/extractor/tvnow.py
deleted file mode 100644 (file)
index 0acc306..0000000
+++ /dev/null
@@ -1,639 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..compat import compat_str
-from ..utils import (
-    ExtractorError,
-    get_element_by_id,
-    int_or_none,
-    parse_iso8601,
-    parse_duration,
-    str_or_none,
-    try_get,
-    update_url_query,
-    urljoin,
-)
-
-
-class TVNowBaseIE(InfoExtractor):
-    _VIDEO_FIELDS = (
-        'id', 'title', 'free', 'geoblocked', 'articleLong', 'articleShort',
-        'broadcastStartDate', 'isDrm', 'duration', 'season', 'episode',
-        'manifest.dashclear', 'manifest.hlsclear', 'manifest.smoothclear',
-        'format.title', 'format.defaultImage169Format', 'format.defaultImage169Logo')
-
-    def _call_api(self, path, video_id, query):
-        return self._download_json(
-            'https://api.tvnow.de/v3/' + path, video_id, query=query)
-
-    def _extract_video(self, info, display_id):
-        video_id = compat_str(info['id'])
-        title = info['title']
-
-        paths = []
-        for manifest_url in (info.get('manifest') or {}).values():
-            if not manifest_url:
-                continue
-            manifest_url = update_url_query(manifest_url, {'filter': ''})
-            path = self._search_regex(r'https?://[^/]+/(.+?)\.ism/', manifest_url, 'path')
-            if path in paths:
-                continue
-            paths.append(path)
-
-            def url_repl(proto, suffix):
-                return re.sub(
-                    r'(?:hls|dash|hss)([.-])', proto + r'\1', re.sub(
-                        r'\.ism/(?:[^.]*\.(?:m3u8|mpd)|[Mm]anifest)',
-                        '.ism/' + suffix, manifest_url))
-
-            def make_urls(proto, suffix):
-                urls = [url_repl(proto, suffix)]
-                hd_url = urls[0].replace('/manifest/', '/ngvod/')
-                if hd_url != urls[0]:
-                    urls.append(hd_url)
-                return urls
-
-            for man_url in make_urls('dash', '.mpd'):
-                formats = self._extract_mpd_formats(
-                    man_url, video_id, mpd_id='dash', fatal=False)
-            for man_url in make_urls('hss', 'Manifest'):
-                formats.extend(self._extract_ism_formats(
-                    man_url, video_id, ism_id='mss', fatal=False))
-            for man_url in make_urls('hls', '.m3u8'):
-                formats.extend(self._extract_m3u8_formats(
-                    man_url, video_id, 'mp4', 'm3u8_native', m3u8_id='hls',
-                    fatal=False))
-            if formats:
-                break
-        else:
-            if not self.get_param('allow_unplayable_formats') and info.get('isDrm'):
-                raise ExtractorError(
-                    'Video %s is DRM protected' % video_id, expected=True)
-            if info.get('geoblocked'):
-                raise self.raise_geo_restricted()
-            if not info.get('free', True):
-                raise ExtractorError(
-                    'Video %s is not available for free' % video_id, expected=True)
-
-        description = info.get('articleLong') or info.get('articleShort')
-        timestamp = parse_iso8601(info.get('broadcastStartDate'), ' ')
-        duration = parse_duration(info.get('duration'))
-
-        f = info.get('format', {})
-
-        thumbnails = [{
-            'url': 'https://aistvnow-a.akamaihd.net/tvnow/movie/%s' % video_id,
-        }]
-        thumbnail = f.get('defaultImage169Format') or f.get('defaultImage169Logo')
-        if thumbnail:
-            thumbnails.append({
-                'url': thumbnail,
-            })
-
-        return {
-            'id': video_id,
-            'display_id': display_id,
-            'title': title,
-            'description': description,
-            'thumbnails': thumbnails,
-            'timestamp': timestamp,
-            'duration': duration,
-            'series': f.get('title'),
-            'season_number': int_or_none(info.get('season')),
-            'episode_number': int_or_none(info.get('episode')),
-            'episode': title,
-            'formats': formats,
-        }
-
-
-class TVNowIE(TVNowBaseIE):
-    _VALID_URL = r'''(?x)
-                    https?://
-                        (?:www\.)?tvnow\.(?:de|at|ch)/(?P<station>[^/]+)/
-                        (?P<show_id>[^/]+)/
-                        (?!(?:list|jahr)(?:/|$))(?P<id>[^/?\#&]+)
-                    '''
-
-    @classmethod
-    def suitable(cls, url):
-        return (False if TVNowNewIE.suitable(url) or TVNowSeasonIE.suitable(url) or TVNowAnnualIE.suitable(url) or TVNowShowIE.suitable(url)
-                else super(TVNowIE, cls).suitable(url))
-
-    _TESTS = [{
-        'url': 'https://www.tvnow.de/rtl2/grip-das-motormagazin/der-neue-porsche-911-gt-3/player',
-        'info_dict': {
-            'id': '331082',
-            'display_id': 'grip-das-motormagazin/der-neue-porsche-911-gt-3',
-            'ext': 'mp4',
-            'title': 'Der neue Porsche 911 GT 3',
-            'description': 'md5:6143220c661f9b0aae73b245e5d898bb',
-            'timestamp': 1495994400,
-            'upload_date': '20170528',
-            'duration': 5283,
-            'series': 'GRIP - Das Motormagazin',
-            'season_number': 14,
-            'episode_number': 405,
-            'episode': 'Der neue Porsche 911 GT 3',
-        },
-    }, {
-        # rtl2
-        'url': 'https://www.tvnow.de/rtl2/armes-deutschland/episode-0008/player',
-        'only_matching': True,
-    }, {
-        # rtlnitro
-        'url': 'https://www.tvnow.de/nitro/alarm-fuer-cobra-11-die-autobahnpolizei/auf-eigene-faust-pilot/player',
-        'only_matching': True,
-    }, {
-        # superrtl
-        'url': 'https://www.tvnow.de/superrtl/die-lustigsten-schlamassel-der-welt/u-a-ketchup-effekt/player',
-        'only_matching': True,
-    }, {
-        # ntv
-        'url': 'https://www.tvnow.de/ntv/startup-news/goetter-in-weiss/player',
-        'only_matching': True,
-    }, {
-        # vox
-        'url': 'https://www.tvnow.de/vox/auto-mobil/neues-vom-automobilmarkt-2017-11-19-17-00-00/player',
-        'only_matching': True,
-    }, {
-        # rtlplus
-        'url': 'https://www.tvnow.de/rtlplus/op-ruft-dr-bruckner/die-vernaehte-frau/player',
-        'only_matching': True,
-    }, {
-        'url': 'https://www.tvnow.de/rtl2/grip-das-motormagazin/der-neue-porsche-911-gt-3',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        mobj = self._match_valid_url(url)
-        display_id = '%s/%s' % mobj.group(2, 3)
-
-        info = self._call_api(
-            'movies/' + display_id, display_id, query={
-                'fields': ','.join(self._VIDEO_FIELDS),
-            })
-
-        return self._extract_video(info, display_id)
-
-
-class TVNowNewIE(InfoExtractor):
-    _VALID_URL = r'''(?x)
-                    (?P<base_url>https?://
-                        (?:www\.)?tvnow\.(?:de|at|ch)/
-                        (?:shows|serien))/
-                        (?P<show>[^/]+)-\d+/
-                        [^/]+/
-                        episode-\d+-(?P<episode>[^/?$&]+)-(?P<id>\d+)
-                    '''
-
-    _TESTS = [{
-        'url': 'https://www.tvnow.de/shows/grip-das-motormagazin-1669/2017-05/episode-405-der-neue-porsche-911-gt-3-331082',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        mobj = self._match_valid_url(url)
-        base_url = re.sub(r'(?:shows|serien)', '_', mobj.group('base_url'))
-        show, episode = mobj.group('show', 'episode')
-        return self.url_result(
-            # Rewrite new URLs to the old format and use extraction via old API
-            # at api.tvnow.de as a loophole for bypassing premium content checks
-            '%s/%s/%s' % (base_url, show, episode),
-            ie=TVNowIE.ie_key(), video_id=mobj.group('id'))
-
-
-class TVNowFilmIE(TVNowBaseIE):
-    _VALID_URL = r'''(?x)
-                    (?P<base_url>https?://
-                        (?:www\.)?tvnow\.(?:de|at|ch)/
-                        (?:filme))/
-                        (?P<title>[^/?$&]+)-(?P<id>\d+)
-                    '''
-    _TESTS = [{
-        'url': 'https://www.tvnow.de/filme/lord-of-war-haendler-des-todes-7959',
-        'info_dict': {
-            'id': '1426690',
-            'display_id': 'lord-of-war-haendler-des-todes',
-            'ext': 'mp4',
-            'title': 'Lord of War',
-            'description': 'md5:5eda15c0d5b8cb70dac724c8a0ff89a9',
-            'timestamp': 1550010000,
-            'upload_date': '20190212',
-            'duration': 7016,
-        },
-    }, {
-        'url': 'https://www.tvnow.de/filme/the-machinist-12157',
-        'info_dict': {
-            'id': '328160',
-            'display_id': 'the-machinist',
-            'ext': 'mp4',
-            'title': 'The Machinist',
-            'description': 'md5:9a0e363fdd74b3a9e1cdd9e21d0ecc28',
-            'timestamp': 1496469720,
-            'upload_date': '20170603',
-            'duration': 5836,
-        },
-    }, {
-        'url': 'https://www.tvnow.de/filme/horst-schlaemmer-isch-kandidiere-17777',
-        'only_matching': True,  # DRM protected
-    }]
-
-    def _real_extract(self, url):
-        mobj = self._match_valid_url(url)
-        display_id = mobj.group('title')
-
-        webpage = self._download_webpage(url, display_id, fatal=False)
-        if not webpage:
-            raise ExtractorError('Cannot download "%s"' % url, expected=True)
-
-        json_text = get_element_by_id('now-web-state', webpage)
-        if not json_text:
-            raise ExtractorError('Cannot read video data', expected=True)
-
-        json_data = self._parse_json(
-            json_text,
-            display_id,
-            transform_source=lambda x: x.replace('&q;', '"'),
-            fatal=False)
-        if not json_data:
-            raise ExtractorError('Cannot read video data', expected=True)
-
-        player_key = next(
-            (key for key in json_data.keys() if 'module/player' in key),
-            None)
-        page_key = next(
-            (key for key in json_data.keys() if 'page/filme' in key),
-            None)
-        movie_id = try_get(
-            json_data,
-            [
-                lambda x: x[player_key]['body']['id'],
-                lambda x: x[page_key]['body']['modules'][0]['id'],
-                lambda x: x[page_key]['body']['modules'][1]['id']],
-            int)
-        if not movie_id:
-            raise ExtractorError('Cannot extract movie ID', expected=True)
-
-        info = self._call_api(
-            'movies/%d' % movie_id,
-            display_id,
-            query={'fields': ','.join(self._VIDEO_FIELDS)})
-
-        return self._extract_video(info, display_id)
-
-
-class TVNowNewBaseIE(InfoExtractor):
-    def _call_api(self, path, video_id, query={}):
-        result = self._download_json(
-            'https://apigw.tvnow.de/module/' + path, video_id, query=query)
-        error = result.get('error')
-        if error:
-            raise ExtractorError(
-                '%s said: %s' % (self.IE_NAME, error), expected=True)
-        return result
-
-
-r"""
-TODO: new apigw.tvnow.de based version of TVNowIE. Replace old TVNowIE with it
-when api.tvnow.de is shut down. This version can't bypass premium checks though.
-class TVNowIE(TVNowNewBaseIE):
-    _VALID_URL = r'''(?x)
-                    https?://
-                        (?:www\.)?tvnow\.(?:de|at|ch)/
-                        (?:shows|serien)/[^/]+/
-                        (?:[^/]+/)+
-                        (?P<display_id>[^/?$&]+)-(?P<id>\d+)
-                    '''
-
-    _TESTS = [{
-        # episode with annual navigation
-        'url': 'https://www.tvnow.de/shows/grip-das-motormagazin-1669/2017-05/episode-405-der-neue-porsche-911-gt-3-331082',
-        'info_dict': {
-            'id': '331082',
-            'display_id': 'grip-das-motormagazin/der-neue-porsche-911-gt-3',
-            'ext': 'mp4',
-            'title': 'Der neue Porsche 911 GT 3',
-            'description': 'md5:6143220c661f9b0aae73b245e5d898bb',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'timestamp': 1495994400,
-            'upload_date': '20170528',
-            'duration': 5283,
-            'series': 'GRIP - Das Motormagazin',
-            'season_number': 14,
-            'episode_number': 405,
-            'episode': 'Der neue Porsche 911 GT 3',
-        },
-    }, {
-        # rtl2, episode with season navigation
-        'url': 'https://www.tvnow.de/shows/armes-deutschland-11471/staffel-3/episode-14-bernd-steht-seit-der-trennung-von-seiner-frau-allein-da-526124',
-        'only_matching': True,
-    }, {
-        # rtlnitro
-        'url': 'https://www.tvnow.de/serien/alarm-fuer-cobra-11-die-autobahnpolizei-1815/staffel-13/episode-5-auf-eigene-faust-pilot-366822',
-        'only_matching': True,
-    }, {
-        # superrtl
-        'url': 'https://www.tvnow.de/shows/die-lustigsten-schlamassel-der-welt-1221/staffel-2/episode-14-u-a-ketchup-effekt-364120',
-        'only_matching': True,
-    }, {
-        # ntv
-        'url': 'https://www.tvnow.de/shows/startup-news-10674/staffel-2/episode-39-goetter-in-weiss-387630',
-        'only_matching': True,
-    }, {
-        # vox
-        'url': 'https://www.tvnow.de/shows/auto-mobil-174/2017-11/episode-46-neues-vom-automobilmarkt-2017-11-19-17-00-00-380072',
-        'only_matching': True,
-    }, {
-        'url': 'https://www.tvnow.de/shows/grip-das-motormagazin-1669/2017-05/episode-405-der-neue-porsche-911-gt-3-331082',
-        'only_matching': True,
-    }]
-
-    def _extract_video(self, info, url, display_id):
-        config = info['config']
-        source = config['source']
-
-        video_id = compat_str(info.get('id') or source['videoId'])
-        title = source['title'].strip()
-
-        paths = []
-        for manifest_url in (info.get('manifest') or {}).values():
-            if not manifest_url:
-                continue
-            manifest_url = update_url_query(manifest_url, {'filter': ''})
-            path = self._search_regex(r'https?://[^/]+/(.+?)\.ism/', manifest_url, 'path')
-            if path in paths:
-                continue
-            paths.append(path)
-
-            def url_repl(proto, suffix):
-                return re.sub(
-                    r'(?:hls|dash|hss)([.-])', proto + r'\1', re.sub(
-                        r'\.ism/(?:[^.]*\.(?:m3u8|mpd)|[Mm]anifest)',
-                        '.ism/' + suffix, manifest_url))
-
-            formats = self._extract_mpd_formats(
-                url_repl('dash', '.mpd'), video_id,
-                mpd_id='dash', fatal=False)
-            formats.extend(self._extract_ism_formats(
-                url_repl('hss', 'Manifest'),
-                video_id, ism_id='mss', fatal=False))
-            formats.extend(self._extract_m3u8_formats(
-                url_repl('hls', '.m3u8'), video_id, 'mp4',
-                'm3u8_native', m3u8_id='hls', fatal=False))
-            if formats:
-                break
-        else:
-            if try_get(info, lambda x: x['rights']['isDrm']):
-                raise ExtractorError(
-                    'Video %s is DRM protected' % video_id, expected=True)
-            if try_get(config, lambda x: x['boards']['geoBlocking']['block']):
-                raise self.raise_geo_restricted()
-            if not info.get('free', True):
-                raise ExtractorError(
-                    'Video %s is not available for free' % video_id, expected=True)
-
-        description = source.get('description')
-        thumbnail = url_or_none(source.get('poster'))
-        timestamp = unified_timestamp(source.get('previewStart'))
-        duration = parse_duration(source.get('length'))
-
-        series = source.get('format')
-        season_number = int_or_none(self._search_regex(
-            r'staffel-(\d+)', url, 'season number', default=None))
-        episode_number = int_or_none(self._search_regex(
-            r'episode-(\d+)', url, 'episode number', default=None))
-
-        return {
-            'id': video_id,
-            'display_id': display_id,
-            'title': title,
-            'description': description,
-            'thumbnail': thumbnail,
-            'timestamp': timestamp,
-            'duration': duration,
-            'series': series,
-            'season_number': season_number,
-            'episode_number': episode_number,
-            'episode': title,
-            'formats': formats,
-        }
-
-    def _real_extract(self, url):
-        display_id, video_id = self._match_valid_url(url).groups()
-        info = self._call_api('player/' + video_id, video_id)
-        return self._extract_video(info, video_id, display_id)
-
-
-class TVNowFilmIE(TVNowIE):  # XXX: Do not subclass from concrete IE
-    _VALID_URL = r'''(?x)
-                    (?P<base_url>https?://
-                        (?:www\.)?tvnow\.(?:de|at|ch)/
-                        (?:filme))/
-                        (?P<title>[^/?$&]+)-(?P<id>\d+)
-                    '''
-    _TESTS = [{
-        'url': 'https://www.tvnow.de/filme/lord-of-war-haendler-des-todes-7959',
-        'info_dict': {
-            'id': '1426690',
-            'display_id': 'lord-of-war-haendler-des-todes',
-            'ext': 'mp4',
-            'title': 'Lord of War',
-            'description': 'md5:5eda15c0d5b8cb70dac724c8a0ff89a9',
-            'timestamp': 1550010000,
-            'upload_date': '20190212',
-            'duration': 7016,
-        },
-    }, {
-        'url': 'https://www.tvnow.de/filme/the-machinist-12157',
-        'info_dict': {
-            'id': '328160',
-            'display_id': 'the-machinist',
-            'ext': 'mp4',
-            'title': 'The Machinist',
-            'description': 'md5:9a0e363fdd74b3a9e1cdd9e21d0ecc28',
-            'timestamp': 1496469720,
-            'upload_date': '20170603',
-            'duration': 5836,
-        },
-    }, {
-        'url': 'https://www.tvnow.de/filme/horst-schlaemmer-isch-kandidiere-17777',
-        'only_matching': True,  # DRM protected
-    }]
-
-    def _real_extract(self, url):
-        mobj = self._match_valid_url(url)
-        display_id = mobj.group('title')
-
-        webpage = self._download_webpage(url, display_id, fatal=False)
-        if not webpage:
-            raise ExtractorError('Cannot download "%s"' % url, expected=True)
-
-        json_text = get_element_by_id('now-web-state', webpage)
-        if not json_text:
-            raise ExtractorError('Cannot read video data', expected=True)
-
-        json_data = self._parse_json(
-            json_text,
-            display_id,
-            transform_source=lambda x: x.replace('&q;', '"'),
-            fatal=False)
-        if not json_data:
-            raise ExtractorError('Cannot read video data', expected=True)
-
-        player_key = next(
-            (key for key in json_data.keys() if 'module/player' in key),
-            None)
-        page_key = next(
-            (key for key in json_data.keys() if 'page/filme' in key),
-            None)
-        movie_id = try_get(
-            json_data,
-            [
-                lambda x: x[player_key]['body']['id'],
-                lambda x: x[page_key]['body']['modules'][0]['id'],
-                lambda x: x[page_key]['body']['modules'][1]['id']],
-            int)
-        if not movie_id:
-            raise ExtractorError('Cannot extract movie ID', expected=True)
-
-        info = self._call_api('player/%d' % movie_id, display_id)
-        return self._extract_video(info, url, display_id)
-"""
-
-
-class TVNowListBaseIE(TVNowNewBaseIE):
-    _SHOW_VALID_URL = r'''(?x)
-                    (?P<base_url>
-                        https?://
-                            (?:www\.)?tvnow\.(?:de|at|ch)/(?:shows|serien)/
-                            [^/?#&]+-(?P<show_id>\d+)
-                    )
-                    '''
-
-    @classmethod
-    def suitable(cls, url):
-        return (False if TVNowNewIE.suitable(url)
-                else super(TVNowListBaseIE, cls).suitable(url))
-
-    def _extract_items(self, url, show_id, list_id, query):
-        items = self._call_api(
-            'teaserrow/format/episode/' + show_id, list_id,
-            query=query)['items']
-
-        entries = []
-        for item in items:
-            if not isinstance(item, dict):
-                continue
-            item_url = urljoin(url, item.get('url'))
-            if not item_url:
-                continue
-            video_id = str_or_none(item.get('id') or item.get('videoId'))
-            item_title = item.get('subheadline') or item.get('text')
-            entries.append(self.url_result(
-                item_url, ie=TVNowNewIE.ie_key(), video_id=video_id,
-                video_title=item_title))
-
-        return self.playlist_result(entries, '%s/%s' % (show_id, list_id))
-
-
-class TVNowSeasonIE(TVNowListBaseIE):
-    _VALID_URL = r'%s/staffel-(?P<id>\d+)' % TVNowListBaseIE._SHOW_VALID_URL
-    _TESTS = [{
-        'url': 'https://www.tvnow.de/serien/alarm-fuer-cobra-11-die-autobahnpolizei-1815/staffel-13',
-        'info_dict': {
-            'id': '1815/13',
-        },
-        'playlist_mincount': 22,
-    }]
-
-    def _real_extract(self, url):
-        _, show_id, season_id = self._match_valid_url(url).groups()
-        return self._extract_items(
-            url, show_id, season_id, {'season': season_id})
-
-
-class TVNowAnnualIE(TVNowListBaseIE):
-    _VALID_URL = r'%s/(?P<year>\d{4})-(?P<month>\d{2})' % TVNowListBaseIE._SHOW_VALID_URL
-    _TESTS = [{
-        'url': 'https://www.tvnow.de/shows/grip-das-motormagazin-1669/2017-05',
-        'info_dict': {
-            'id': '1669/2017-05',
-        },
-        'playlist_mincount': 2,
-    }]
-
-    def _real_extract(self, url):
-        _, show_id, year, month = self._match_valid_url(url).groups()
-        return self._extract_items(
-            url, show_id, '%s-%s' % (year, month), {
-                'year': int(year),
-                'month': int(month),
-            })
-
-
-class TVNowShowIE(TVNowListBaseIE):
-    _VALID_URL = TVNowListBaseIE._SHOW_VALID_URL
-    _TESTS = [{
-        # annual navigationType
-        'url': 'https://www.tvnow.de/shows/grip-das-motormagazin-1669',
-        'info_dict': {
-            'id': '1669',
-        },
-        'playlist_mincount': 73,
-    }, {
-        # season navigationType
-        'url': 'https://www.tvnow.de/shows/armes-deutschland-11471',
-        'info_dict': {
-            'id': '11471',
-        },
-        'playlist_mincount': 3,
-    }]
-
-    @classmethod
-    def suitable(cls, url):
-        return (False if TVNowNewIE.suitable(url) or TVNowSeasonIE.suitable(url) or TVNowAnnualIE.suitable(url)
-                else super(TVNowShowIE, cls).suitable(url))
-
-    def _real_extract(self, url):
-        base_url, show_id = self._match_valid_url(url).groups()
-
-        result = self._call_api(
-            'teaserrow/format/navigation/' + show_id, show_id)
-
-        items = result['items']
-
-        entries = []
-        navigation = result.get('navigationType')
-        if navigation == 'annual':
-            for item in items:
-                if not isinstance(item, dict):
-                    continue
-                year = int_or_none(item.get('year'))
-                if year is None:
-                    continue
-                months = item.get('months')
-                if not isinstance(months, list):
-                    continue
-                for month_dict in months:
-                    if not isinstance(month_dict, dict) or not month_dict:
-                        continue
-                    month_number = int_or_none(list(month_dict.keys())[0])
-                    if month_number is None:
-                        continue
-                    entries.append(self.url_result(
-                        '%s/%04d-%02d' % (base_url, year, month_number),
-                        ie=TVNowAnnualIE.ie_key()))
-        elif navigation == 'season':
-            for item in items:
-                if not isinstance(item, dict):
-                    continue
-                season_number = int_or_none(item.get('season'))
-                if season_number is None:
-                    continue
-                entries.append(self.url_result(
-                    '%s/staffel-%d' % (base_url, season_number),
-                    ie=TVNowSeasonIE.ie_key()))
-        else:
-            raise ExtractorError('Unknown navigationType')
-
-        return self.playlist_result(entries, show_id)
diff --git a/yt_dlp/extractor/twentyfourvideo.py b/yt_dlp/extractor/twentyfourvideo.py
deleted file mode 100644 (file)
index baeb85d..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    parse_iso8601,
-    int_or_none,
-    xpath_attr,
-    xpath_element,
-)
-
-
-class TwentyFourVideoIE(InfoExtractor):
-    IE_NAME = '24video'
-    _VALID_URL = r'''(?x)
-                    https?://
-                        (?P<host>
-                            (?:(?:www|porno?)\.)?24video\.
-                            (?:net|me|xxx|sexy?|tube|adult|site|vip)
-                        )/
-                        (?:
-                            video/(?:(?:view|xml)/)?|
-                            player/new24_play\.swf\?id=
-                        )
-                        (?P<id>\d+)
-                    '''
-
-    _TESTS = [{
-        'url': 'http://www.24video.net/video/view/1044982',
-        'md5': 'e09fc0901d9eaeedac872f154931deeb',
-        'info_dict': {
-            'id': '1044982',
-            'ext': 'mp4',
-            'title': 'Эротика каменного века',
-            'description': 'Как смотрели порно в каменном веке.',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'uploader': 'SUPERTELO',
-            'duration': 31,
-            'timestamp': 1275937857,
-            'upload_date': '20100607',
-            'age_limit': 18,
-            'like_count': int,
-            'dislike_count': int,
-        },
-    }, {
-        'url': 'http://www.24video.net/player/new24_play.swf?id=1044982',
-        'only_matching': True,
-    }, {
-        'url': 'http://www.24video.me/video/view/1044982',
-        'only_matching': True,
-    }, {
-        'url': 'http://www.24video.tube/video/view/2363750',
-        'only_matching': True,
-    }, {
-        'url': 'https://www.24video.site/video/view/2640421',
-        'only_matching': True,
-    }, {
-        'url': 'https://porno.24video.net/video/2640421-vsya-takaya-gibkaya-i-v-masle',
-        'only_matching': True,
-    }, {
-        'url': 'https://www.24video.vip/video/view/1044982',
-        'only_matching': True,
-    }, {
-        'url': 'https://porn.24video.net/video/2640421-vsya-takay',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        mobj = self._match_valid_url(url)
-        video_id = mobj.group('id')
-        host = mobj.group('host')
-
-        webpage = self._download_webpage(
-            'http://%s/video/view/%s' % (host, video_id), video_id)
-
-        title = self._og_search_title(webpage)
-        description = self._html_search_regex(
-            r'<(p|span)[^>]+itemprop="description"[^>]*>(?P<description>[^<]+)</\1>',
-            webpage, 'description', fatal=False, group='description')
-        thumbnail = self._og_search_thumbnail(webpage)
-        duration = int_or_none(self._og_search_property(
-            'duration', webpage, 'duration', fatal=False))
-        timestamp = parse_iso8601(self._search_regex(
-            r'<time[^>]+\bdatetime="([^"]+)"[^>]+itemprop="uploadDate"',
-            webpage, 'upload date', fatal=False))
-
-        uploader = self._html_search_regex(
-            r'class="video-uploaded"[^>]*>\s*<a href="/jsecUser/movies/[^"]+"[^>]*>([^<]+)</a>',
-            webpage, 'uploader', fatal=False)
-
-        view_count = int_or_none(self._html_search_regex(
-            r'<span class="video-views">(\d+) просмотр',
-            webpage, 'view count', fatal=False))
-        comment_count = int_or_none(self._html_search_regex(
-            r'<a[^>]+href="#tab-comments"[^>]*>(\d+) комментари',
-            webpage, 'comment count', default=None))
-
-        # Sets some cookies
-        self._download_xml(
-            r'http://%s/video/xml/%s?mode=init' % (host, video_id),
-            video_id, 'Downloading init XML')
-
-        video_xml = self._download_xml(
-            'http://%s/video/xml/%s?mode=play' % (host, video_id),
-            video_id, 'Downloading video XML')
-
-        video = xpath_element(video_xml, './/video', 'video', fatal=True)
-
-        formats = [{
-            'url': xpath_attr(video, '', 'url', 'video URL', fatal=True),
-        }]
-
-        like_count = int_or_none(video.get('ratingPlus'))
-        dislike_count = int_or_none(video.get('ratingMinus'))
-        age_limit = 18 if video.get('adult') == 'true' else 0
-
-        return {
-            'id': video_id,
-            'title': title,
-            'description': description,
-            'thumbnail': thumbnail,
-            'uploader': uploader,
-            'duration': duration,
-            'timestamp': timestamp,
-            'view_count': view_count,
-            'comment_count': comment_count,
-            'like_count': like_count,
-            'dislike_count': dislike_count,
-            'age_limit': age_limit,
-            'formats': formats,
-        }
diff --git a/yt_dlp/extractor/unscripted.py b/yt_dlp/extractor/unscripted.py
deleted file mode 100644 (file)
index 6643a71..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-from .common import InfoExtractor
-from ..utils import parse_duration, traverse_obj
-
-
-class UnscriptedNewsVideoIE(InfoExtractor):
-    _VALID_URL = r'https?://www\.unscripted\.news/videos/(?P<id>[\w-]+)'
-    _TESTS = [{
-        'url': 'https://www.unscripted.news/videos/a-day-at-the-farmers-protest',
-        'info_dict': {
-            'id': '60c0a55cd1e99b1079918a57',
-            'display_id': 'a-day-at-the-farmers-protest',
-            'ext': 'mp4',
-            'title': 'A Day at the Farmers\' Protest',
-            'description': 'md5:4b3df22747a03e8f14f746dd72190384',
-            'thumbnail': 'https://s3.unscripted.news/anj2/60c0a55cd1e99b1079918a57/5f199a65-c803-4a5c-8fce-2077359c3b72.jpg',
-            'duration': 2251.0,
-            'series': 'Ground Reports',
-        }
-    }, {
-        'url': 'https://www.unscripted.news/videos/you-get-the-politicians-you-deserve-ft-shashi-tharoor',
-        'info_dict': {
-            'id': '5fb3afbf18ac817d341a74d8',
-            'display_id': 'you-get-the-politicians-you-deserve-ft-shashi-tharoor',
-            'ext': 'mp4',
-            'cast': ['Avalok Langer', 'Ashwin Mehta'],
-            'thumbnail': 'https://s3.unscripted.news/anj2/5fb3afbf18ac817d341a74d8/82bd7942-4f20-4cd8-98ae-83f9e814f998.jpg',
-            'description': 'md5:1e91b069238a705ca3a40f87e6f1182c',
-            'duration': 1046.0,
-            'series': 'Dumb Questions Only',
-            'title': 'You Get The Politicians You Deserve! ft. Shashi Tharoor',
-        }
-    }]
-
-    def _real_extract(self, url):
-        display_id = self._match_id(url)
-        webpage = self._download_webpage(url, display_id)
-        nextjs_data = self._search_nextjs_data(webpage, display_id)['props']['pageProps']['dataLocal']
-
-        # TODO: get subtitle from srt key
-        formats, subtitles = self._extract_m3u8_formats_and_subtitles(nextjs_data['alt_content'], display_id)
-
-        return {
-            'id': nextjs_data['_id'],
-            'display_id': display_id,
-            'title': nextjs_data.get('title') or self._og_search_title(webpage),
-            'description': nextjs_data.get('sh_heading') or self._og_search_description(webpage),
-            'formats': formats,
-            'subtitles': subtitles,
-            'thumbnail': self._og_search_thumbnail(webpage),
-            'duration': parse_duration(nextjs_data.get('duration')),
-            'series': traverse_obj(nextjs_data, ('show', 'topic')),
-            'cast': traverse_obj(nextjs_data, ('cast_crew', ..., 'displayname')),
-        }
diff --git a/yt_dlp/extractor/veehd.py b/yt_dlp/extractor/veehd.py
deleted file mode 100644 (file)
index 5ecd887..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-import re
-import json
-
-from .common import InfoExtractor
-from ..compat import (
-    compat_urllib_parse_unquote,
-    compat_urlparse,
-)
-from ..utils import (
-    ExtractorError,
-    clean_html,
-    get_element_by_id,
-)
-
-
-class VeeHDIE(InfoExtractor):
-    _VALID_URL = r'https?://veehd\.com/video/(?P<id>\d+)'
-
-    # Seems VeeHD videos have multiple copies on several servers, all of
-    # whom have different MD5 checksums, so omit md5 field in all tests
-    _TESTS = [{
-        'url': 'http://veehd.com/video/4639434_Solar-Sinter',
-        'info_dict': {
-            'id': '4639434',
-            'ext': 'mp4',
-            'title': 'Solar Sinter',
-            'uploader_id': 'VideoEyes',
-            'description': 'md5:46a840e8692ddbaffb5f81d9885cb457',
-        },
-        'skip': 'Video deleted',
-    }, {
-        'url': 'http://veehd.com/video/4905758_Elysian-Fields-Channeling',
-        'info_dict': {
-            'id': '4905758',
-            'ext': 'mp4',
-            'title': 'Elysian Fields - Channeling',
-            'description': 'md5:360e4e95fdab58aefbea0f2a19e5604b',
-            'uploader_id': 'spotted',
-        }
-    }, {
-        'url': 'http://veehd.com/video/2046729_2012-2009-DivX-Trailer',
-        'info_dict': {
-            'id': '2046729',
-            'ext': 'avi',
-            'title': '2012 (2009) DivX Trailer',
-            'description': 'md5:75435ee95255e6a9838ac6f6f3a2396b',
-            'uploader_id': 'Movie_Trailers',
-        }
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        # VeeHD seems to send garbage on the first request.
-        # See https://github.com/ytdl-org/youtube-dl/issues/2102
-        self._download_webpage(url, video_id, 'Requesting webpage')
-        webpage = self._download_webpage(url, video_id)
-
-        if 'This video has been removed<' in webpage:
-            raise ExtractorError('Video %s has been removed' % video_id, expected=True)
-
-        player_path = self._search_regex(
-            r'\$\("#playeriframe"\).attr\({src : "(.+?)"',
-            webpage, 'player path')
-        player_url = compat_urlparse.urljoin(url, player_path)
-
-        self._download_webpage(player_url, video_id, 'Requesting player page')
-        player_page = self._download_webpage(
-            player_url, video_id, 'Downloading player page')
-
-        video_url = None
-
-        config_json = self._search_regex(
-            r'value=\'config=({.+?})\'', player_page, 'config json', default=None)
-
-        if config_json:
-            config = json.loads(config_json)
-            video_url = compat_urllib_parse_unquote(config['clip']['url'])
-
-        if not video_url:
-            video_url = self._html_search_regex(
-                r'<embed[^>]+type="video/divx"[^>]+src="([^"]+)"',
-                player_page, 'video url', default=None)
-
-        if not video_url:
-            iframe_src = self._search_regex(
-                r'<iframe[^>]+src="/?([^"]+)"', player_page, 'iframe url')
-            iframe_url = 'http://veehd.com/%s' % iframe_src
-
-            self._download_webpage(iframe_url, video_id, 'Requesting iframe page')
-            iframe_page = self._download_webpage(
-                iframe_url, video_id, 'Downloading iframe page')
-
-            video_url = self._search_regex(
-                r"file\s*:\s*'([^']+)'", iframe_page, 'video url')
-
-        title = clean_html(get_element_by_id('videoName', webpage).rpartition('|')[0])
-        uploader_id = self._html_search_regex(
-            r'<a href="/profile/\d+">(.+?)</a>',
-            webpage, 'uploader')
-        thumbnail = self._search_regex(
-            r'<img id="veehdpreview" src="(.+?)"',
-            webpage, 'thumbnail')
-        description = self._html_search_regex(
-            r'<td class="infodropdown".*?<div>(.*?)<ul',
-            webpage, 'description', flags=re.DOTALL)
-
-        return {
-            '_type': 'video',
-            'id': video_id,
-            'title': title,
-            'url': video_url,
-            'uploader_id': uploader_id,
-            'thumbnail': thumbnail,
-            'description': description,
-        }
index 8a7126853907ad3ad4f03ece997a1ea279036d3f..1a2d667e70c05d933db7d661545cdeb680bedc17 100644 (file)
@@ -302,12 +302,6 @@ def _url_res(video_url, ie_key):
         if vice_url:
             return _url_res(vice_url, ViceIE.ie_key())
 
         if vice_url:
             return _url_res(vice_url, ViceIE.ie_key())
 
-        embed_code = self._search_regex(
-            r'embedCode=([^&\'"]+)', body,
-            'ooyala embed code', default=None)
-        if embed_code:
-            return _url_res('ooyala:%s' % embed_code, 'Ooyala')
-
         youtube_url = YoutubeIE._extract_url(body)
         if youtube_url:
             return _url_res(youtube_url, YoutubeIE.ie_key())
         youtube_url = YoutubeIE._extract_url(body)
         if youtube_url:
             return _url_res(youtube_url, YoutubeIE.ie_key())
diff --git a/yt_dlp/extractor/vidbit.py b/yt_dlp/extractor/vidbit.py
deleted file mode 100644 (file)
index 2813032..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-from .common import InfoExtractor
-from ..compat import compat_urlparse
-from ..utils import (
-    int_or_none,
-    js_to_json,
-    remove_end,
-    unified_strdate,
-)
-
-
-class VidbitIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?vidbit\.co/(?:watch|embed)\?.*?\bv=(?P<id>[\da-zA-Z]+)'
-    _TESTS = [{
-        'url': 'http://www.vidbit.co/watch?v=jkL2yDOEq2',
-        'md5': '1a34b7f14defe3b8fafca9796892924d',
-        'info_dict': {
-            'id': 'jkL2yDOEq2',
-            'ext': 'mp4',
-            'title': 'Intro to VidBit',
-            'description': 'md5:5e0d6142eec00b766cbf114bfd3d16b7',
-            'thumbnail': r're:https?://.*\.jpg$',
-            'upload_date': '20160618',
-            'view_count': int,
-            'comment_count': int,
-        }
-    }, {
-        'url': 'http://www.vidbit.co/embed?v=jkL2yDOEq2&auto=0&water=0',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        webpage = self._download_webpage(
-            compat_urlparse.urljoin(url, '/watch?v=%s' % video_id), video_id)
-
-        video_url, title = [None] * 2
-
-        config = self._parse_json(self._search_regex(
-            r'(?s)\.setup\(({.+?})\);', webpage, 'setup', default='{}'),
-            video_id, transform_source=js_to_json)
-        if config:
-            if config.get('file'):
-                video_url = compat_urlparse.urljoin(url, config['file'])
-            title = config.get('title')
-
-        if not video_url:
-            video_url = compat_urlparse.urljoin(url, self._search_regex(
-                r'file\s*:\s*(["\'])(?P<url>(?:(?!\1).)+)\1',
-                webpage, 'video URL', group='url'))
-
-        if not title:
-            title = remove_end(
-                self._html_search_regex(
-                    (r'<h1>(.+?)</h1>', r'<title>(.+?)</title>'),
-                    webpage, 'title', default=None) or self._og_search_title(webpage),
-                ' - VidBit')
-
-        description = self._html_search_meta(
-            ('description', 'og:description', 'twitter:description'),
-            webpage, 'description')
-
-        upload_date = unified_strdate(self._html_search_meta(
-            'datePublished', webpage, 'upload date'))
-
-        view_count = int_or_none(self._search_regex(
-            r'<strong>(\d+)</strong> views',
-            webpage, 'view count', fatal=False))
-        comment_count = int_or_none(self._search_regex(
-            r'id=["\']cmt_num["\'][^>]*>\((\d+)\)',
-            webpage, 'comment count', fatal=False))
-
-        return {
-            'id': video_id,
-            'url': video_url,
-            'title': title,
-            'description': description,
-            'thumbnail': self._og_search_thumbnail(webpage),
-            'upload_date': upload_date,
-            'view_count': view_count,
-            'comment_count': comment_count,
-        }
diff --git a/yt_dlp/extractor/vimple.py b/yt_dlp/extractor/vimple.py
deleted file mode 100644 (file)
index fdccf46..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-from .common import InfoExtractor
-from ..utils import int_or_none
-
-
-class SprutoBaseIE(InfoExtractor):
-    def _extract_spruto(self, spruto, video_id):
-        playlist = spruto['playlist'][0]
-        title = playlist['title']
-        video_id = playlist.get('videoId') or video_id
-        thumbnail = playlist.get('posterUrl') or playlist.get('thumbnailUrl')
-        duration = int_or_none(playlist.get('duration'))
-
-        formats = [{
-            'url': f['url'],
-        } for f in playlist['video']]
-
-        return {
-            'id': video_id,
-            'title': title,
-            'thumbnail': thumbnail,
-            'duration': duration,
-            'formats': formats,
-        }
-
-
-class VimpleIE(SprutoBaseIE):
-    IE_DESC = 'Vimple - one-click video hosting'
-    _VALID_URL = r'https?://(?:player\.vimple\.(?:ru|co)/iframe|vimple\.(?:ru|co))/(?P<id>[\da-f-]{32,36})'
-    _TESTS = [{
-        'url': 'http://vimple.ru/c0f6b1687dcd4000a97ebe70068039cf',
-        'md5': '2e750a330ed211d3fd41821c6ad9a279',
-        'info_dict': {
-            'id': 'c0f6b168-7dcd-4000-a97e-be70068039cf',
-            'ext': 'mp4',
-            'title': 'Sunset',
-            'duration': 20,
-            'thumbnail': r're:https?://.*?\.jpg',
-        },
-    }, {
-        'url': 'http://player.vimple.ru/iframe/52e1beec-1314-4a83-aeac-c61562eadbf9',
-        'only_matching': True,
-    }, {
-        'url': 'http://vimple.co/04506a053f124483b8fb05ed73899f19',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        webpage = self._download_webpage(
-            'http://player.vimple.ru/iframe/%s' % video_id, video_id)
-
-        spruto = self._parse_json(
-            self._search_regex(
-                r'sprutoData\s*:\s*({.+?}),\r\n', webpage, 'spruto data'),
-            video_id)
-
-        return self._extract_spruto(spruto, video_id)
diff --git a/yt_dlp/extractor/vodlocker.py b/yt_dlp/extractor/vodlocker.py
deleted file mode 100644 (file)
index b215d6c..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-from .common import InfoExtractor
-from ..networking import Request
-from ..utils import NO_DEFAULT, ExtractorError, urlencode_postdata
-
-
-class VodlockerIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?vodlocker\.(?:com|city)/(?:embed-)?(?P<id>[0-9a-zA-Z]+)(?:\..*?)?'
-
-    _TESTS = [{
-        'url': 'http://vodlocker.com/e8wvyzz4sl42',
-        'md5': 'ce0c2d18fa0735f1bd91b69b0e54aacf',
-        'info_dict': {
-            'id': 'e8wvyzz4sl42',
-            'ext': 'mp4',
-            'title': 'Germany vs Brazil',
-            'thumbnail': r're:http://.*\.jpg',
-        },
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-
-        if any(p in webpage for p in (
-                '>THIS FILE WAS DELETED<',
-                '>File Not Found<',
-                'The file you were looking for could not be found, sorry for any inconvenience.<',
-                '>The file was removed')):
-            raise ExtractorError('Video %s does not exist' % video_id, expected=True)
-
-        fields = self._hidden_inputs(webpage)
-
-        if fields['op'] == 'download1':
-            self._sleep(3, video_id)  # they do detect when requests happen too fast!
-            post = urlencode_postdata(fields)
-            req = Request(url, post)
-            req.headers['Content-type'] = 'application/x-www-form-urlencoded'
-            webpage = self._download_webpage(
-                req, video_id, 'Downloading video page')
-
-        def extract_file_url(html, default=NO_DEFAULT):
-            return self._search_regex(
-                r'file:\s*"(http[^\"]+)",', html, 'file url', default=default)
-
-        video_url = extract_file_url(webpage, default=None)
-
-        if not video_url:
-            embed_url = self._search_regex(
-                r'<iframe[^>]+src=(["\'])(?P<url>(?:https?://)?vodlocker\.(?:com|city)/embed-.+?)\1',
-                webpage, 'embed url', group='url')
-            embed_webpage = self._download_webpage(
-                embed_url, video_id, 'Downloading embed webpage')
-            video_url = extract_file_url(embed_webpage)
-            thumbnail_webpage = embed_webpage
-        else:
-            thumbnail_webpage = webpage
-
-        title = self._search_regex(
-            r'id="file_title".*?>\s*(.*?)\s*<(?:br|span)', webpage, 'title')
-        thumbnail = self._search_regex(
-            r'image:\s*"(http[^\"]+)",', thumbnail_webpage, 'thumbnail', fatal=False)
-
-        formats = [{
-            'format_id': 'sd',
-            'url': video_url,
-        }]
-
-        return {
-            'id': video_id,
-            'title': title,
-            'thumbnail': thumbnail,
-            'formats': formats,
-        }
diff --git a/yt_dlp/extractor/voicerepublic.py b/yt_dlp/extractor/voicerepublic.py
deleted file mode 100644 (file)
index 47502af..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-from .common import InfoExtractor
-from ..compat import compat_str
-from ..utils import (
-    ExtractorError,
-    determine_ext,
-    int_or_none,
-    urljoin,
-)
-
-
-class VoiceRepublicIE(InfoExtractor):
-    _VALID_URL = r'https?://voicerepublic\.com/(?:talks|embed)/(?P<id>[0-9a-z-]+)'
-    _TESTS = [{
-        'url': 'http://voicerepublic.com/talks/watching-the-watchers-building-a-sousveillance-state',
-        'md5': 'b9174d651323f17783000876347116e3',
-        'info_dict': {
-            'id': '2296',
-            'display_id': 'watching-the-watchers-building-a-sousveillance-state',
-            'ext': 'm4a',
-            'title': 'Watching the Watchers: Building a Sousveillance State',
-            'description': 'Secret surveillance programs have metadata too. The people and companies that operate secret surveillance programs can be surveilled.',
-            'duration': 1556,
-            'view_count': int,
-        }
-    }, {
-        'url': 'http://voicerepublic.com/embed/watching-the-watchers-building-a-sousveillance-state',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        display_id = self._match_id(url)
-
-        webpage = self._download_webpage(url, display_id)
-
-        if '>Queued for processing, please stand by...<' in webpage:
-            raise ExtractorError(
-                'Audio is still queued for processing', expected=True)
-
-        talk = self._parse_json(self._search_regex(
-            r'initialSnapshot\s*=\s*({.+?});',
-            webpage, 'talk'), display_id)['talk']
-        title = talk['title']
-        formats = [{
-            'url': urljoin(url, talk_url),
-            'format_id': format_id,
-            'ext': determine_ext(talk_url) or format_id,
-            'vcodec': 'none',
-        } for format_id, talk_url in talk['media_links'].items()]
-
-        return {
-            'id': compat_str(talk.get('id') or display_id),
-            'display_id': display_id,
-            'title': title,
-            'description': talk.get('teaser'),
-            'thumbnail': talk.get('image_url'),
-            'duration': int_or_none(talk.get('archived_duration')),
-            'view_count': int_or_none(talk.get('play_count')),
-            'formats': formats,
-        }
index b19a279344da867e21f378bbd0bb2e7116190fca..ef77bedd27ef13fa41ff3ccd13912b1311451fc3 100644 (file)
@@ -81,6 +81,7 @@ def _real_initialize(self):
 
 
 class VootIE(VootBaseIE):
 
 
 class VootIE(VootBaseIE):
+    _WORKING = False
     _VALID_URL = r'''(?x)
                     (?:
                         voot:|
     _VALID_URL = r'''(?x)
                     (?:
                         voot:|
@@ -169,6 +170,7 @@ def _real_extract(self, url):
 
 
 class VootSeriesIE(VootBaseIE):
 
 
 class VootSeriesIE(VootBaseIE):
+    _WORKING = False
     _VALID_URL = r'https?://(?:www\.)?voot\.com/shows/[^/]+/(?P<id>\d{3,})'
     _TESTS = [{
         'url': 'https://www.voot.com/shows/chakravartin-ashoka-samrat/100002',
     _VALID_URL = r'https?://(?:www\.)?voot\.com/shows/[^/]+/(?P<id>\d{3,})'
     _TESTS = [{
         'url': 'https://www.voot.com/shows/chakravartin-ashoka-samrat/100002',
index f9362002f2b82890c99b98f0ea0e7d5a1475fa71..f36908754f36e2c099d3a722fea32114a7fea8ab 100644 (file)
@@ -51,7 +51,7 @@ def _real_extract(self, url):
             info['duration'] = int_or_none(asset.get('duration'))
             return info
 
             info['duration'] = int_or_none(asset.get('duration'))
             return info
 
-        for provider_video_type in ('ooyala', 'youtube', 'brightcove'):
+        for provider_video_type in ('youtube', 'brightcove'):
             provider_video_id = video_data.get('%s_id' % provider_video_type)
             if not provider_video_id:
                 continue
             provider_video_id = video_data.get('%s_id' % provider_video_type)
             if not provider_video_id:
                 continue
@@ -177,7 +177,6 @@ def _real_extract(self, url):
         def create_entry(provider_video_id, provider_video_type, title=None, description=None):
             video_url = {
                 'youtube': '%s',
         def create_entry(provider_video_id, provider_video_type, title=None, description=None):
             video_url = {
                 'youtube': '%s',
-                'ooyala': 'ooyala:%s',
                 'volume': 'http://volume.vox-cdn.com/embed/%s',
             }[provider_video_type] % provider_video_id
             return {
                 'volume': 'http://volume.vox-cdn.com/embed/%s',
             }[provider_video_type] % provider_video_id
             return {
@@ -205,11 +204,6 @@ def create_entry(provider_video_id, provider_video_type, title=None, description
                         provider_video_id, provider_video_type,
                         video_data.get('title'), video_data.get('description')))
 
                         provider_video_id, provider_video_type,
                         video_data.get('title'), video_data.get('description')))
 
-        provider_video_id = self._search_regex(
-            r'data-ooyala-id="([^"]+)"', webpage, 'ooyala id', default=None)
-        if provider_video_id:
-            entries.append(create_entry(provider_video_id, 'ooyala'))
-
         volume_uuid = self._search_regex(
             r'data-volume-uuid="([^"]+)"', webpage, 'volume uuid', default=None)
         if volume_uuid:
         volume_uuid = self._search_regex(
             r'data-volume-uuid="([^"]+)"', webpage, 'volume uuid', default=None)
         if volume_uuid:
diff --git a/yt_dlp/extractor/vrak.py b/yt_dlp/extractor/vrak.py
deleted file mode 100644 (file)
index 198c0a2..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from .brightcove import BrightcoveNewIE
-from ..utils import (
-    int_or_none,
-    parse_age_limit,
-    smuggle_url,
-    unescapeHTML,
-)
-
-
-class VrakIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?vrak\.tv/videos\?.*?\btarget=(?P<id>[\d.]+)'
-    _TEST = {
-        'url': 'http://www.vrak.tv/videos?target=1.2306782&filtre=emission&id=1.1806721',
-        'info_dict': {
-            'id': '5345661243001',
-            'ext': 'mp4',
-            'title': 'Obésité, film de hockey et Roseline Filion',
-            'timestamp': 1488492126,
-            'upload_date': '20170302',
-            'uploader_id': '2890187628001',
-            'creator': 'VRAK.TV',
-            'age_limit': 8,
-            'series': 'ALT (Actualité Légèrement Tordue)',
-            'episode': 'Obésité, film de hockey et Roseline Filion',
-            'tags': list,
-        },
-        'params': {
-            'skip_download': True,
-        },
-    }
-    BRIGHTCOVE_URL_TEMPLATE = 'http://players.brightcove.net/2890187628001/default_default/index.html?videoId=%s'
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        webpage = self._download_webpage(url, video_id)
-
-        title = self._html_search_regex(
-            r'<h\d\b[^>]+\bclass=["\']videoTitle["\'][^>]*>([^<]+)',
-            webpage, 'title', default=None) or self._og_search_title(webpage)
-
-        content = self._parse_json(
-            self._search_regex(
-                r'data-player-options-content=(["\'])(?P<content>{.+?})\1',
-                webpage, 'content', default='{}', group='content'),
-            video_id, transform_source=unescapeHTML)
-
-        ref_id = content.get('refId') or self._search_regex(
-            r'refId&quot;:&quot;([^&]+)&quot;', webpage, 'ref id')
-
-        brightcove_id = self._search_regex(
-            r'''(?x)
-                java\.lang\.String\s+value\s*=\s*["']brightcove\.article\.\d+\.%s
-                [^>]*
-                java\.lang\.String\s+value\s*=\s*["'](\d+)
-            ''' % re.escape(ref_id), webpage, 'brightcove id')
-
-        return {
-            '_type': 'url_transparent',
-            'ie_key': BrightcoveNewIE.ie_key(),
-            'url': smuggle_url(
-                self.BRIGHTCOVE_URL_TEMPLATE % brightcove_id,
-                {'geo_countries': ['CA']}),
-            'id': brightcove_id,
-            'description': content.get('description'),
-            'creator': content.get('brand'),
-            'age_limit': parse_age_limit(content.get('rating')),
-            'series': content.get('showName') or content.get(
-                'episodeName'),  # this is intentional
-            'season_number': int_or_none(content.get('seasonNumber')),
-            'episode': title,
-            'episode_number': int_or_none(content.get('episodeNumber')),
-            'tags': content.get('tags', []),
-        }
diff --git a/yt_dlp/extractor/vrv.py b/yt_dlp/extractor/vrv.py
deleted file mode 100644 (file)
index 523c442..0000000
+++ /dev/null
@@ -1,269 +0,0 @@
-import base64
-import hashlib
-import hmac
-import json
-import random
-import string
-import time
-import urllib.parse
-
-from .common import InfoExtractor
-from ..compat import compat_urllib_parse_urlencode
-from ..networking.exceptions import HTTPError
-from ..utils import (
-    ExtractorError,
-    float_or_none,
-    int_or_none,
-    join_nonempty,
-    traverse_obj,
-)
-
-
-class VRVBaseIE(InfoExtractor):
-    _API_DOMAIN = None
-    _API_PARAMS = {}
-    _CMS_SIGNING = {}
-    _TOKEN = None
-    _TOKEN_SECRET = ''
-
-    def _call_api(self, path, video_id, note, data=None):
-        # https://tools.ietf.org/html/rfc5849#section-3
-        base_url = self._API_DOMAIN + '/core/' + path
-        query = [
-            ('oauth_consumer_key', self._API_PARAMS['oAuthKey']),
-            ('oauth_nonce', ''.join(random.choices(string.ascii_letters, k=32))),
-            ('oauth_signature_method', 'HMAC-SHA1'),
-            ('oauth_timestamp', int(time.time())),
-        ]
-        if self._TOKEN:
-            query.append(('oauth_token', self._TOKEN))
-        encoded_query = compat_urllib_parse_urlencode(query)
-        headers = self.geo_verification_headers()
-        if data:
-            data = json.dumps(data).encode()
-            headers['Content-Type'] = 'application/json'
-        base_string = '&'.join([
-            'POST' if data else 'GET',
-            urllib.parse.quote(base_url, ''),
-            urllib.parse.quote(encoded_query, '')])
-        oauth_signature = base64.b64encode(hmac.new(
-            (self._API_PARAMS['oAuthSecret'] + '&' + self._TOKEN_SECRET).encode('ascii'),
-            base_string.encode(), hashlib.sha1).digest()).decode()
-        encoded_query += '&oauth_signature=' + urllib.parse.quote(oauth_signature, '')
-        try:
-            return self._download_json(
-                '?'.join([base_url, encoded_query]), video_id,
-                note='Downloading %s JSON metadata' % note, headers=headers, data=data)
-        except ExtractorError as e:
-            if isinstance(e.cause, HTTPError) and e.cause.status == 401:
-                raise ExtractorError(json.loads(e.cause.response.read().decode())['message'], expected=True)
-            raise
-
-    def _call_cms(self, path, video_id, note):
-        if not self._CMS_SIGNING:
-            index = self._call_api('index', video_id, 'CMS Signing')
-            self._CMS_SIGNING = index.get('cms_signing') or {}
-            if not self._CMS_SIGNING:
-                for signing_policy in index.get('signing_policies', []):
-                    signing_path = signing_policy.get('path')
-                    if signing_path and signing_path.startswith('/cms/'):
-                        name, value = signing_policy.get('name'), signing_policy.get('value')
-                        if name and value:
-                            self._CMS_SIGNING[name] = value
-        return self._download_json(
-            self._API_DOMAIN + path, video_id, query=self._CMS_SIGNING,
-            note='Downloading %s JSON metadata' % note, headers=self.geo_verification_headers())
-
-    def _get_cms_resource(self, resource_key, video_id):
-        return self._call_api(
-            'cms_resource', video_id, 'resource path', data={
-                'resource_key': resource_key,
-            })['__links__']['cms_resource']['href']
-
-    def _extract_vrv_formats(self, url, video_id, stream_format, audio_lang, hardsub_lang):
-        if not url or stream_format not in ('hls', 'dash', 'adaptive_hls'):
-            return []
-        format_id = join_nonempty(
-            stream_format,
-            audio_lang and 'audio-%s' % audio_lang,
-            hardsub_lang and 'hardsub-%s' % hardsub_lang)
-        if 'hls' in stream_format:
-            adaptive_formats = self._extract_m3u8_formats(
-                url, video_id, 'mp4', m3u8_id=format_id,
-                note='Downloading %s information' % format_id,
-                fatal=False)
-        elif stream_format == 'dash':
-            adaptive_formats = self._extract_mpd_formats(
-                url, video_id, mpd_id=format_id,
-                note='Downloading %s information' % format_id,
-                fatal=False)
-        if audio_lang:
-            for f in adaptive_formats:
-                if f.get('acodec') != 'none':
-                    f['language'] = audio_lang
-        return adaptive_formats
-
-    def _set_api_params(self):
-        webpage = self._download_webpage(
-            'https://vrv.co/', None, headers=self.geo_verification_headers())
-        self._API_PARAMS = self._parse_json(self._search_regex(
-            [
-                r'window\.__APP_CONFIG__\s*=\s*({.+?})(?:</script>|;)',
-                r'window\.__APP_CONFIG__\s*=\s*({.+})'
-            ], webpage, 'app config'), None)['cxApiParams']
-        self._API_DOMAIN = self._API_PARAMS.get('apiDomain', 'https://api.vrv.co')
-
-
-class VRVIE(VRVBaseIE):
-    IE_NAME = 'vrv'
-    _VALID_URL = r'https?://(?:www\.)?vrv\.co/watch/(?P<id>[A-Z0-9]+)'
-    _TESTS = [{
-        'url': 'https://vrv.co/watch/GR9PNZ396/Hidden-America-with-Jonah-Ray:BOSTON-WHERE-THE-PAST-IS-THE-PRESENT',
-        'info_dict': {
-            'id': 'GR9PNZ396',
-            'ext': 'mp4',
-            'title': 'BOSTON: WHERE THE PAST IS THE PRESENT',
-            'description': 'md5:4ec8844ac262ca2df9e67c0983c6b83f',
-            'uploader_id': 'seeso',
-        },
-        'params': {
-            # m3u8 download
-            'skip_download': True,
-        },
-    }, {
-        # movie listing
-        'url': 'https://vrv.co/watch/G6NQXZ1J6/Lily-CAT',
-        'info_dict': {
-            'id': 'G6NQXZ1J6',
-            'title': 'Lily C.A.T',
-            'description': 'md5:988b031e7809a6aeb60968be4af7db07',
-        },
-        'playlist_count': 2,
-    }]
-    _NETRC_MACHINE = 'vrv'
-
-    def _perform_login(self, username, password):
-        token_credentials = self._call_api(
-            'authenticate/by:credentials', None, 'Token Credentials', data={
-                'email': username,
-                'password': password,
-            })
-        self._TOKEN = token_credentials['oauth_token']
-        self._TOKEN_SECRET = token_credentials['oauth_token_secret']
-
-    def _initialize_pre_login(self):
-        return self._set_api_params()
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        object_data = self._call_cms(self._get_cms_resource(
-            'cms:/objects/' + video_id, video_id), video_id, 'object')['items'][0]
-        resource_path = object_data['__links__']['resource']['href']
-        video_data = self._call_cms(resource_path, video_id, 'video')
-        title = video_data['title']
-        description = video_data.get('description')
-
-        if video_data.get('__class__') == 'movie_listing':
-            items = self._call_cms(
-                video_data['__links__']['movie_listing/movies']['href'],
-                video_id, 'movie listing').get('items') or []
-            if len(items) != 1:
-                entries = []
-                for item in items:
-                    item_id = item.get('id')
-                    if not item_id:
-                        continue
-                    entries.append(self.url_result(
-                        'https://vrv.co/watch/' + item_id,
-                        self.ie_key(), item_id, item.get('title')))
-                return self.playlist_result(entries, video_id, title, description)
-            video_data = items[0]
-
-        streams_path = video_data['__links__'].get('streams', {}).get('href')
-        if not streams_path:
-            self.raise_login_required()
-        streams_json = self._call_cms(streams_path, video_id, 'streams')
-
-        audio_locale = streams_json.get('audio_locale')
-        formats = []
-        for stream_type, streams in streams_json.get('streams', {}).items():
-            if stream_type in ('adaptive_hls', 'adaptive_dash'):
-                for stream in streams.values():
-                    formats.extend(self._extract_vrv_formats(
-                        stream.get('url'), video_id, stream_type.split('_')[1],
-                        audio_locale, stream.get('hardsub_locale')))
-
-        subtitles = {}
-        for k in ('captions', 'subtitles'):
-            for subtitle in streams_json.get(k, {}).values():
-                subtitle_url = subtitle.get('url')
-                if not subtitle_url:
-                    continue
-                subtitles.setdefault(subtitle.get('locale', 'en-US'), []).append({
-                    'url': subtitle_url,
-                    'ext': subtitle.get('format', 'ass'),
-                })
-
-        thumbnails = []
-        for thumbnail in traverse_obj(video_data, ('images', 'thumbnail', ..., ...)) or []:
-            thumbnail_url = thumbnail.get('source')
-            if not thumbnail_url:
-                continue
-            thumbnails.append({
-                'url': thumbnail_url,
-                'width': int_or_none(thumbnail.get('width')),
-                'height': int_or_none(thumbnail.get('height')),
-            })
-
-        return {
-            'id': video_id,
-            'title': title,
-            'formats': formats,
-            'subtitles': subtitles,
-            'thumbnails': thumbnails,
-            'description': description,
-            'duration': float_or_none(video_data.get('duration_ms'), 1000),
-            'uploader_id': video_data.get('channel_id'),
-            'series': video_data.get('series_title'),
-            'season': video_data.get('season_title'),
-            'season_number': int_or_none(video_data.get('season_number')),
-            'season_id': video_data.get('season_id'),
-            'episode': title,
-            'episode_number': int_or_none(video_data.get('episode_number')),
-            'episode_id': video_data.get('production_episode_id'),
-        }
-
-
-class VRVSeriesIE(VRVBaseIE):
-    IE_NAME = 'vrv:series'
-    _VALID_URL = r'https?://(?:www\.)?vrv\.co/series/(?P<id>[A-Z0-9]+)'
-    _TEST = {
-        'url': 'https://vrv.co/series/G68VXG3G6/The-Perfect-Insider',
-        'info_dict': {
-            'id': 'G68VXG3G6',
-        },
-        'playlist_mincount': 11,
-    }
-
-    def _initialize_pre_login(self):
-        return self._set_api_params()
-
-    def _real_extract(self, url):
-        series_id = self._match_id(url)
-
-        seasons_path = self._get_cms_resource(
-            'cms:/seasons?series_id=' + series_id, series_id)
-        seasons_data = self._call_cms(seasons_path, series_id, 'seasons')
-
-        entries = []
-        for season in seasons_data.get('items', []):
-            episodes_path = season['__links__']['season/episodes']['href']
-            episodes = self._call_cms(episodes_path, series_id, 'episodes')
-            for episode in episodes.get('items', []):
-                episode_id = episode['id']
-                entries.append(self.url_result(
-                    'https://vrv.co/watch/' + episode_id,
-                    'VRV', episode_id, episode.get('title')))
-
-        return self.playlist_result(entries, series_id)
diff --git a/yt_dlp/extractor/vshare.py b/yt_dlp/extractor/vshare.py
deleted file mode 100644 (file)
index 443ed43..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-from .common import InfoExtractor
-from ..utils import ExtractorError, decode_packed_codes
-
-
-class VShareIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?vshare\.io/[dv]/(?P<id>[^/?#&]+)'
-    _EMBED_REGEX = [r'<iframe[^>]+?src=["\'](?P<url>(?:https?:)?//(?:www\.)?vshare\.io/v/[^/?#&]+)']
-    _TESTS = [{
-        'url': 'https://vshare.io/d/0f64ce6',
-        'md5': '17b39f55b5497ae8b59f5fbce8e35886',
-        'info_dict': {
-            'id': '0f64ce6',
-            'title': 'vl14062007715967',
-            'ext': 'mp4',
-        }
-    }, {
-        'url': 'https://vshare.io/v/0f64ce6/width-650/height-430/1',
-        'only_matching': True,
-    }]
-
-    def _extract_packed(self, webpage):
-        packed = self._search_regex(
-            r'(eval\(function.+)', webpage, 'packed code')
-        unpacked = decode_packed_codes(packed)
-        digits = self._search_regex(r'\[([\d,]+)\]', unpacked, 'digits')
-        digits = [int(digit) for digit in digits.split(',')]
-        key_digit = self._search_regex(
-            r'fromCharCode\(.+?(\d+)\)}', unpacked, 'key digit')
-        chars = [chr(d - int(key_digit)) for d in digits]
-        return ''.join(chars)
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        webpage = self._download_webpage(
-            'https://vshare.io/v/%s/width-650/height-430/1' % video_id,
-            video_id, headers={'Referer': url})
-
-        title = self._html_extract_title(webpage)
-        title = title.split(' - ')[0]
-
-        error = self._html_search_regex(
-            r'(?s)<div[^>]+\bclass=["\']xxx-error[^>]+>(.+?)</div', webpage,
-            'error', default=None)
-        if error:
-            raise ExtractorError(error, expected=True)
-
-        info = self._parse_html5_media_entries(
-            url, '<video>%s</video>' % self._extract_packed(webpage),
-            video_id)[0]
-
-        info.update({
-            'id': video_id,
-            'title': title,
-        })
-
-        return info
diff --git a/yt_dlp/extractor/vupload.py b/yt_dlp/extractor/vupload.py
deleted file mode 100644 (file)
index 23ea70c..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    parse_duration,
-    parse_filesize,
-    extract_attributes,
-    int_or_none,
-    js_to_json
-)
-
-
-class VuploadIE(InfoExtractor):
-    _VALID_URL = r'https://vupload\.com/v/(?P<id>[a-z0-9]+)'
-    _TESTS = [{
-        'url': 'https://vupload.com/v/u28d0pl2tphy',
-        'md5': '9b42a4a193cca64d80248e58527d83c8',
-        'info_dict': {
-            'id': 'u28d0pl2tphy',
-            'ext': 'mp4',
-            'description': 'md5:e9e6c0045c78cbf0d5bb19a55ce199fb',
-            'title': 'md5:e9e6c0045c78cbf0d5bb19a55ce199fb',
-        }
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-
-        title = self._html_extract_title(webpage)
-        video_json = self._parse_json(self._html_search_regex(r'sources:\s*(.+?]),', webpage, 'video'), video_id, transform_source=js_to_json)
-        formats = []
-        for source in video_json:
-            if source['src'].endswith('.m3u8'):
-                formats.extend(self._extract_m3u8_formats(source['src'], video_id, m3u8_id='hls'))
-        duration = parse_duration(self._html_search_regex(
-            r'<i\s*class=["\']fad\s*fa-clock["\']></i>\s*([\d:]+)\s*</div>', webpage, 'duration', fatal=False))
-        filesize_approx = parse_filesize(self._html_search_regex(
-            r'<i\s*class=["\']fad\s*fa-save["\']></i>\s*([^<]+)\s*</div>', webpage, 'filesize', fatal=False))
-        extra_video_info = extract_attributes(self._html_search_regex(
-            r'(<video[^>]+>)', webpage, 'video_info', fatal=False))
-        description = self._html_search_meta('description', webpage)
-
-        return {
-            'id': video_id,
-            'formats': formats,
-            'duration': duration,
-            'filesize_approx': filesize_approx,
-            'width': int_or_none(extra_video_info.get('width')),
-            'height': int_or_none(extra_video_info.get('height')),
-            'format_id': extra_video_info.get('height', '') + 'p',
-            'title': title,
-            'description': description,
-        }
diff --git a/yt_dlp/extractor/vyborymos.py b/yt_dlp/extractor/vyborymos.py
deleted file mode 100644 (file)
index 3865187..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-from .common import InfoExtractor
-from ..compat import compat_str
-
-
-class VyboryMosIE(InfoExtractor):
-    _VALID_URL = r'https?://vybory\.mos\.ru/(?:#precinct/|account/channels\?.*?\bstation_id=)(?P<id>\d+)'
-    _TESTS = [{
-        'url': 'http://vybory.mos.ru/#precinct/13636',
-        'info_dict': {
-            'id': '13636',
-            'ext': 'mp4',
-            'title': 're:^Участковая избирательная комиссия №2231 [0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}$',
-            'description': 'Россия, Москва, улица Введенского, 32А',
-            'is_live': True,
-        },
-        'params': {
-            'skip_download': True,
-        }
-    }, {
-        'url': 'http://vybory.mos.ru/account/channels?station_id=13636',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        station_id = self._match_id(url)
-
-        channels = self._download_json(
-            'http://vybory.mos.ru/account/channels?station_id=%s' % station_id,
-            station_id, 'Downloading channels JSON')
-
-        formats = []
-        for cam_num, (sid, hosts, name, _) in enumerate(channels, 1):
-            for num, host in enumerate(hosts, 1):
-                formats.append({
-                    'url': 'http://%s/master.m3u8?sid=%s' % (host, sid),
-                    'ext': 'mp4',
-                    'format_id': 'camera%d-host%d' % (cam_num, num),
-                    'format_note': '%s, %s' % (name, host),
-                })
-
-        info = self._download_json(
-            'http://vybory.mos.ru/json/voting_stations/%s/%s.json'
-            % (compat_str(station_id)[:3], station_id),
-            station_id, 'Downloading station JSON', fatal=False) or {}
-
-        return {
-            'id': station_id,
-            'title': info.get('name') or station_id,
-            'description': info.get('address'),
-            'is_live': True,
-            'formats': formats,
-        }
diff --git a/yt_dlp/extractor/vzaar.py b/yt_dlp/extractor/vzaar.py
deleted file mode 100644 (file)
index 19908a9..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-from .common import InfoExtractor
-from ..compat import compat_str
-from ..utils import (
-    int_or_none,
-    float_or_none,
-    unified_timestamp,
-    url_or_none,
-)
-
-
-class VzaarIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:(?:www|view)\.)?vzaar\.com/(?:videos/)?(?P<id>\d+)'
-    _EMBED_REGEX = [r'<iframe[^>]+src=["\'](?P<url>(?:https?:)?//(?:view\.vzaar\.com)/[0-9]+)']
-    _TESTS = [{
-        # HTTP and HLS
-        'url': 'https://vzaar.com/videos/1152805',
-        'md5': 'bde5ddfeb104a6c56a93a06b04901dbf',
-        'info_dict': {
-            'id': '1152805',
-            'ext': 'mp4',
-            'title': 'sample video (public)',
-        },
-    }, {
-        'url': 'https://view.vzaar.com/27272/player',
-        'md5': '3b50012ac9bbce7f445550d54e0508f2',
-        'info_dict': {
-            'id': '27272',
-            'ext': 'mp3',
-            'title': 'MP3',
-        },
-    }, {
-        # hlsAes = true
-        'url': 'https://view.vzaar.com/11379930/player',
-        'info_dict': {
-            'id': '11379930',
-            'ext': 'mp4',
-            'title': 'Videoaula',
-        },
-        'params': {
-            # m3u8 download
-            'skip_download': True,
-        },
-    }, {
-        # with null videoTitle
-        'url': 'https://view.vzaar.com/20313539/download',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        video_data = self._download_json(
-            'http://view.vzaar.com/v2/%s/video' % video_id, video_id)
-
-        title = video_data.get('videoTitle') or video_id
-
-        formats = []
-
-        source_url = url_or_none(video_data.get('sourceUrl'))
-        if source_url:
-            f = {
-                'url': source_url,
-                'format_id': 'http',
-                'quality': 1,
-            }
-            if 'audio' in source_url:
-                f.update({
-                    'vcodec': 'none',
-                    'ext': 'mp3',
-                })
-            else:
-                f.update({
-                    'width': int_or_none(video_data.get('width')),
-                    'height': int_or_none(video_data.get('height')),
-                    'ext': 'mp4',
-                    'fps': float_or_none(video_data.get('fps')),
-                })
-            formats.append(f)
-
-        video_guid = video_data.get('guid')
-        usp = video_data.get('usp')
-        if video_data.get('uspEnabled') and isinstance(video_guid, compat_str) and isinstance(usp, dict):
-            hls_aes = video_data.get('hlsAes')
-            qs = '&'.join('%s=%s' % (k, v) for k, v in usp.items())
-            url_templ = 'http://%%s.vzaar.com/v5/usp%s/%s/%s.ism%%s?' % ('aes' if hls_aes else '', video_guid, video_id)
-            m3u8_formats = self._extract_m3u8_formats(
-                url_templ % ('fable', '/.m3u8') + qs, video_id, 'mp4', 'm3u8_native',
-                m3u8_id='hls', fatal=False)
-            if hls_aes:
-                for f in m3u8_formats:
-                    f['hls_aes'] = {'uri': url_templ % ('goose', '') + qs}
-            formats.extend(m3u8_formats)
-
-        return {
-            'id': video_id,
-            'title': title,
-            'thumbnail': self._proto_relative_url(video_data.get('poster')),
-            'duration': float_or_none(video_data.get('videoDuration')),
-            'timestamp': unified_timestamp(video_data.get('ts')),
-            'formats': formats,
-        }
diff --git a/yt_dlp/extractor/wakanim.py b/yt_dlp/extractor/wakanim.py
deleted file mode 100644 (file)
index 155008f..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-from urllib.parse import unquote
-
-from .common import InfoExtractor
-from ..utils import (
-    merge_dicts,
-    urljoin,
-)
-
-
-class WakanimIE(InfoExtractor):
-    _VALID_URL = r'https://(?:www\.)?wakanim\.tv/[^/]+/v2/catalogue/episode/(?P<id>\d+)'
-    _TESTS = [{
-        'url': 'https://www.wakanim.tv/de/v2/catalogue/episode/2997/the-asterisk-war-omu-staffel-1-episode-02-omu',
-        'info_dict': {
-            'id': '2997',
-            'ext': 'mp4',
-            'title': 'Episode 02',
-            'description': 'md5:2927701ea2f7e901de8bfa8d39b2852d',
-            'series': 'The Asterisk War  (OmU.)',
-            'season_number': 1,
-            'episode': 'Episode 02',
-            'episode_number': 2,
-        },
-        'params': {
-            'skip_download': True,
-        },
-    }, {
-        # DRM Protected
-        'url': 'https://www.wakanim.tv/de/v2/catalogue/episode/7843/sword-art-online-alicization-omu-arc-2-folge-15-omu',
-        'only_matching': True,
-    }]
-    _GEO_BYPASS = False
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        webpage = self._download_webpage(url, video_id)
-
-        if 'Geoblocking' in webpage:
-            if '/de/' in url:
-                self.raise_geo_restricted(countries=['DE', 'AT', 'CH'])
-            else:
-                self.raise_geo_restricted(countries=['RU'])
-
-        manifest_url = urljoin(url, self._search_regex(
-            r'file\s*:\s*(["\'])(?P<url>(?:(?!\1).)+)\1', webpage, 'manifest url',
-            group='url'))
-        if not self.get_param('allow_unplayable_formats'):
-            # https://docs.microsoft.com/en-us/azure/media-services/previous/media-services-content-protection-overview#streaming-urls
-            encryption = self._search_regex(
-                r'encryption%3D(c(?:enc|bc(?:s-aapl)?))',
-                manifest_url, 'encryption', default=None)
-            if encryption in ('cenc', 'cbcs-aapl'):
-                self.report_drm(video_id)
-
-        if 'format=mpd-time-cmaf' in unquote(manifest_url):
-            formats = self._extract_mpd_formats(
-                manifest_url, video_id, mpd_id='dash')
-        else:
-            formats = self._extract_m3u8_formats(
-                manifest_url, video_id, 'mp4', entry_protocol='m3u8_native',
-                m3u8_id='hls')
-
-        info = self._search_json_ld(webpage, video_id, default={})
-
-        title = self._search_regex(
-            (r'<h1[^>]+\bclass=["\']episode_h1[^>]+\btitle=(["\'])(?P<title>(?:(?!\1).)+)\1',
-             r'<span[^>]+\bclass=["\']episode_title["\'][^>]*>(?P<title>[^<]+)'),
-            webpage, 'title', default=None, group='title')
-
-        return merge_dicts(info, {
-            'id': video_id,
-            'title': title,
-            'formats': formats,
-        })
diff --git a/yt_dlp/extractor/watchbox.py b/yt_dlp/extractor/watchbox.py
deleted file mode 100644 (file)
index c973ca9..0000000
+++ /dev/null
@@ -1,153 +0,0 @@
-from .common import InfoExtractor
-from ..compat import compat_str
-from ..utils import (
-    int_or_none,
-    js_to_json,
-    strip_or_none,
-    try_get,
-    unescapeHTML,
-    unified_timestamp,
-)
-
-
-class WatchBoxIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?watchbox\.de/(?P<kind>serien|filme)/(?:[^/]+/)*[^/]+-(?P<id>\d+)'
-    _TESTS = [{
-        # film
-        'url': 'https://www.watchbox.de/filme/free-jimmy-12325.html',
-        'info_dict': {
-            'id': '341368',
-            'ext': 'mp4',
-            'title': 'Free Jimmy',
-            'description': 'md5:bcd8bafbbf9dc0ef98063d344d7cc5f6',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'duration': 4890,
-            'age_limit': 16,
-            'release_year': 2009,
-        },
-        'params': {
-            'skip_download': True,
-        },
-        'expected_warnings': ['Failed to download m3u8 information'],
-    }, {
-        # episode
-        'url': 'https://www.watchbox.de/serien/ugly-americans-12231/staffel-1/date-in-der-hoelle-328286.html',
-        'info_dict': {
-            'id': '328286',
-            'ext': 'mp4',
-            'title': 'S01 E01 - Date in der Hölle',
-            'description': 'md5:2f31c74a8186899f33cb5114491dae2b',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'duration': 1291,
-            'age_limit': 12,
-            'release_year': 2010,
-            'series': 'Ugly Americans',
-            'season_number': 1,
-            'episode': 'Date in der Hölle',
-            'episode_number': 1,
-        },
-        'params': {
-            'skip_download': True,
-        },
-        'expected_warnings': ['Failed to download m3u8 information'],
-    }, {
-        'url': 'https://www.watchbox.de/serien/ugly-americans-12231/staffel-2/der-ring-des-powers-328270',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        mobj = self._match_valid_url(url)
-        kind, video_id = mobj.group('kind', 'id')
-
-        webpage = self._download_webpage(url, video_id)
-
-        player_config = self._parse_json(
-            self._search_regex(
-                r'data-player-conf=(["\'])(?P<data>{.+?})\1', webpage,
-                'player config', default='{}', group='data'),
-            video_id, transform_source=unescapeHTML, fatal=False)
-
-        if not player_config:
-            player_config = self._parse_json(
-                self._search_regex(
-                    r'playerConf\s*=\s*({.+?})\s*;', webpage, 'player config',
-                    default='{}'),
-                video_id, transform_source=js_to_json, fatal=False) or {}
-
-        source = player_config.get('source') or {}
-
-        video_id = compat_str(source.get('videoId') or video_id)
-
-        devapi = self._download_json(
-            'http://api.watchbox.de/devapi/id/%s' % video_id, video_id, query={
-                'format': 'json',
-                'apikey': 'hbbtv',
-            }, fatal=False)
-
-        item = try_get(devapi, lambda x: x['items'][0], dict) or {}
-
-        title = item.get('title') or try_get(
-            item, lambda x: x['movie']['headline_movie'],
-            compat_str) or source['title']
-
-        formats = []
-        hls_url = item.get('media_videourl_hls') or source.get('hls')
-        if hls_url:
-            formats.extend(self._extract_m3u8_formats(
-                hls_url, video_id, 'mp4', entry_protocol='m3u8_native',
-                m3u8_id='hls', fatal=False))
-        dash_url = item.get('media_videourl_wv') or source.get('dash')
-        if dash_url:
-            formats.extend(self._extract_mpd_formats(
-                dash_url, video_id, mpd_id='dash', fatal=False))
-        mp4_url = item.get('media_videourl')
-        if mp4_url:
-            formats.append({
-                'url': mp4_url,
-                'format_id': 'mp4',
-                'width': int_or_none(item.get('width')),
-                'height': int_or_none(item.get('height')),
-                'tbr': int_or_none(item.get('bitrate')),
-            })
-
-        description = strip_or_none(item.get('descr'))
-        thumbnail = item.get('media_content_thumbnail_large') or source.get('poster') or item.get('media_thumbnail')
-        duration = int_or_none(item.get('media_length') or source.get('length'))
-        timestamp = unified_timestamp(item.get('pubDate'))
-        view_count = int_or_none(item.get('media_views'))
-        age_limit = int_or_none(try_get(item, lambda x: x['movie']['fsk']))
-        release_year = int_or_none(try_get(item, lambda x: x['movie']['rel_year']))
-
-        info = {
-            'id': video_id,
-            'title': title,
-            'description': description,
-            'thumbnail': thumbnail,
-            'duration': duration,
-            'timestamp': timestamp,
-            'view_count': view_count,
-            'age_limit': age_limit,
-            'release_year': release_year,
-            'formats': formats,
-        }
-
-        if kind.lower() == 'serien':
-            series = try_get(
-                item, lambda x: x['special']['title'],
-                compat_str) or source.get('format')
-            season_number = int_or_none(self._search_regex(
-                r'^S(\d{1,2})\s*E\d{1,2}', title, 'season number',
-                default=None) or self._search_regex(
-                    r'/staffel-(\d+)/', url, 'season number', default=None))
-            episode = source.get('title')
-            episode_number = int_or_none(self._search_regex(
-                r'^S\d{1,2}\s*E(\d{1,2})', title, 'episode number',
-                default=None))
-            info.update({
-                'series': series,
-                'season_number': season_number,
-                'episode': episode,
-                'episode_number': episode_number,
-            })
-
-        return info
diff --git a/yt_dlp/extractor/watchindianporn.py b/yt_dlp/extractor/watchindianporn.py
deleted file mode 100644 (file)
index 3ded2d1..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-import re
-
-from .common import InfoExtractor
-from ..utils import parse_duration
-
-
-class WatchIndianPornIE(InfoExtractor):
-    IE_DESC = 'Watch Indian Porn'
-    _VALID_URL = r'https?://(?:www\.)?watchindianporn\.net/(?:[^/]+/)*video/(?P<display_id>[^/]+)-(?P<id>[a-zA-Z0-9]+)\.html'
-    _TEST = {
-        'url': 'http://www.watchindianporn.net/video/hot-milf-from-kerala-shows-off-her-gorgeous-large-breasts-on-camera-RZa2avywNPa.html',
-        'md5': '249589a164dde236ec65832bfce17440',
-        'info_dict': {
-            'id': 'RZa2avywNPa',
-            'display_id': 'hot-milf-from-kerala-shows-off-her-gorgeous-large-breasts-on-camera',
-            'ext': 'mp4',
-            'title': 'Hot milf from kerala shows off her gorgeous large breasts on camera',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'duration': 226,
-            'view_count': int,
-            'categories': list,
-            'age_limit': 18,
-        }
-    }
-
-    def _real_extract(self, url):
-        mobj = self._match_valid_url(url)
-        video_id = mobj.group('id')
-        display_id = mobj.group('display_id')
-
-        webpage = self._download_webpage(url, display_id)
-
-        info_dict = self._parse_html5_media_entries(url, webpage, video_id)[0]
-
-        title = self._html_search_regex((
-            r'<title>(.+?)\s*-\s*Indian\s+Porn</title>',
-            r'<h4>(.+?)</h4>'
-        ), webpage, 'title')
-
-        duration = parse_duration(self._search_regex(
-            r'Time:\s*<strong>\s*(.+?)\s*</strong>',
-            webpage, 'duration', fatal=False))
-
-        view_count = int(self._search_regex(
-            r'(?s)Time:\s*<strong>.*?</strong>.*?<strong>\s*(\d+)\s*</strong>',
-            webpage, 'view count', fatal=False))
-
-        categories = re.findall(
-            r'<a[^>]+class=[\'"]categories[\'"][^>]*>\s*([^<]+)\s*</a>',
-            webpage)
-
-        info_dict.update({
-            'id': video_id,
-            'display_id': display_id,
-            'http_headers': {
-                'Referer': url,
-            },
-            'title': title,
-            'duration': duration,
-            'view_count': view_count,
-            'categories': categories,
-            'age_limit': 18,
-        })
-
-        return info_dict
diff --git a/yt_dlp/extractor/willow.py b/yt_dlp/extractor/willow.py
deleted file mode 100644 (file)
index 0ec9c9d..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-from ..utils import ExtractorError
-from .common import InfoExtractor
-
-
-class WillowIE(InfoExtractor):
-    _VALID_URL = r'https?://(www\.)?willow\.tv/videos/(?P<id>[0-9a-z-_]+)'
-    _GEO_COUNTRIES = ['US']
-
-    _TESTS = [{
-        'url': 'http://willow.tv/videos/d5winning-moment-eng-vs-ind-streaming-online-4th-test-india-tour-of-england-2021',
-        'info_dict': {
-            'id': '169662',
-            'display_id': 'd5winning-moment-eng-vs-ind-streaming-online-4th-test-india-tour-of-england-2021',
-            'ext': 'mp4',
-            'title': 'Winning Moment: 4th Test, England vs India',
-            'thumbnail': 'https://aimages.willow.tv/ytThumbnails/6748_D5winning_moment.jpg',
-            'duration': 233,
-            'timestamp': 1630947954,
-            'upload_date': '20210906',
-            'location': 'Kennington Oval, London',
-            'series': 'India tour of England 2021',
-        },
-        'params': {
-            'skip_download': True,  # AES-encrypted m3u8
-        },
-    }, {
-        'url': 'http://willow.tv/videos/highlights-short-ind-vs-nz-streaming-online-2nd-t20i-new-zealand-tour-of-india-2021',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-        video_data = self._parse_json(self._html_search_regex(
-            r'var\s+data_js\s*=\s*JSON\.parse\(\'(.+)\'\)', webpage,
-            'data_js'), video_id)
-
-        video = next((v for v in video_data.get('trending_videos') or []
-                      if v.get('secureurl')), None)
-        if not video:
-            raise ExtractorError('No videos found')
-
-        formats = self._extract_m3u8_formats(video['secureurl'], video_id, 'mp4')
-
-        return {
-            'id': str(video.get('content_id')),
-            'display_id': video.get('video_slug'),
-            'title': video.get('video_name') or self._html_search_meta('twitter:title', webpage),
-            'formats': formats,
-            'thumbnail': video.get('yt_thumb_url') or self._html_search_meta(
-                'twitter:image', webpage, default=None),
-            'duration': video.get('duration_seconds'),
-            'timestamp': video.get('created_date'),
-            'location': video.get('venue'),
-            'series': video.get('series_name'),
-        }
diff --git a/yt_dlp/extractor/xbef.py b/yt_dlp/extractor/xbef.py
deleted file mode 100644 (file)
index ac69528..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-from .common import InfoExtractor
-from ..compat import compat_urllib_parse_unquote
-
-
-class XBefIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?xbef\.com/video/(?P<id>[0-9]+)'
-    _TEST = {
-        'url': 'http://xbef.com/video/5119-glamourous-lesbians-smoking-drinking-and-fucking',
-        'md5': 'a478b565baff61634a98f5e5338be995',
-        'info_dict': {
-            'id': '5119',
-            'ext': 'mp4',
-            'title': 'md5:7358a9faef8b7b57acda7c04816f170e',
-            'age_limit': 18,
-            'thumbnail': r're:^http://.*\.jpg',
-        }
-    }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-
-        title = self._html_search_regex(
-            r'<h1[^>]*>(.*?)</h1>', webpage, 'title')
-
-        config_url_enc = self._download_webpage(
-            'http://xbef.com/Main/GetVideoURLEncoded/%s' % video_id, video_id,
-            note='Retrieving config URL')
-        config_url = compat_urllib_parse_unquote(config_url_enc)
-        config = self._download_xml(
-            config_url, video_id, note='Retrieving config')
-
-        video_url = config.find('./file').text
-        thumbnail = config.find('./image').text
-
-        return {
-            'id': video_id,
-            'url': video_url,
-            'title': title,
-            'thumbnail': thumbnail,
-            'age_limit': 18,
-        }
diff --git a/yt_dlp/extractor/xtube.py b/yt_dlp/extractor/xtube.py
deleted file mode 100644 (file)
index db82925..0000000
+++ /dev/null
@@ -1,214 +0,0 @@
-import itertools
-import re
-
-from .common import InfoExtractor
-from ..networking import Request
-from ..utils import (
-    int_or_none,
-    js_to_json,
-    orderedSet,
-    parse_duration,
-    str_to_int,
-    url_or_none,
-)
-
-
-class XTubeIE(InfoExtractor):
-    _VALID_URL = r'''(?x)
-                        (?:
-                            xtube:|
-                            https?://(?:www\.)?xtube\.com/(?:watch\.php\?.*\bv=|video-watch/(?:embedded/)?(?P<display_id>[^/]+)-)
-                        )
-                        (?P<id>[^/?&#]+)
-                    '''
-
-    _TESTS = [{
-        # old URL schema
-        'url': 'http://www.xtube.com/watch.php?v=kVTUy_G222_',
-        'md5': '092fbdd3cbe292c920ef6fc6a8a9cdab',
-        'info_dict': {
-            'id': 'kVTUy_G222_',
-            'ext': 'mp4',
-            'title': 'strange erotica',
-            'description': 'contains:an ET kind of thing',
-            'uploader': 'greenshowers',
-            'duration': 450,
-            'view_count': int,
-            'comment_count': int,
-            'age_limit': 18,
-        }
-    }, {
-        # new URL schema
-        'url': 'http://www.xtube.com/video-watch/strange-erotica-625837',
-        'only_matching': True,
-    }, {
-        'url': 'xtube:625837',
-        'only_matching': True,
-    }, {
-        'url': 'xtube:kVTUy_G222_',
-        'only_matching': True,
-    }, {
-        'url': 'https://www.xtube.com/video-watch/embedded/milf-tara-and-teen-shared-and-cum-covered-extreme-bukkake-32203482?embedsize=big',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        mobj = self._match_valid_url(url)
-        video_id = mobj.group('id')
-        display_id = mobj.group('display_id')
-
-        if not display_id:
-            display_id = video_id
-
-        if video_id.isdigit() and len(video_id) < 11:
-            url_pattern = 'http://www.xtube.com/video-watch/-%s'
-        else:
-            url_pattern = 'http://www.xtube.com/watch.php?v=%s'
-
-        webpage = self._download_webpage(
-            url_pattern % video_id, display_id, headers={
-                'Cookie': 'age_verified=1; cookiesAccepted=1',
-            })
-
-        title, thumbnail, duration, sources, media_definition = [None] * 5
-
-        config = self._parse_json(self._search_regex(
-            r'playerConf\s*=\s*({.+?})\s*,\s*(?:\n|loaderConf|playerWrapper)', webpage, 'config',
-            default='{}'), video_id, transform_source=js_to_json, fatal=False)
-        if config:
-            config = config.get('mainRoll')
-            if isinstance(config, dict):
-                title = config.get('title')
-                thumbnail = config.get('poster')
-                duration = int_or_none(config.get('duration'))
-                sources = config.get('sources') or config.get('format')
-                media_definition = config.get('mediaDefinition')
-
-        if not isinstance(sources, dict) and not media_definition:
-            sources = self._parse_json(self._search_regex(
-                r'(["\'])?sources\1?\s*:\s*(?P<sources>{.+?}),',
-                webpage, 'sources', group='sources'), video_id,
-                transform_source=js_to_json)
-
-        formats = []
-        format_urls = set()
-
-        if isinstance(sources, dict):
-            for format_id, format_url in sources.items():
-                format_url = url_or_none(format_url)
-                if not format_url:
-                    continue
-                if format_url in format_urls:
-                    continue
-                format_urls.add(format_url)
-                formats.append({
-                    'url': format_url,
-                    'format_id': format_id,
-                    'height': int_or_none(format_id),
-                })
-
-        if isinstance(media_definition, list):
-            for media in media_definition:
-                video_url = url_or_none(media.get('videoUrl'))
-                if not video_url:
-                    continue
-                if video_url in format_urls:
-                    continue
-                format_urls.add(video_url)
-                format_id = media.get('format')
-                if format_id == 'hls':
-                    formats.extend(self._extract_m3u8_formats(
-                        video_url, video_id, 'mp4', entry_protocol='m3u8_native',
-                        m3u8_id='hls', fatal=False))
-                elif format_id == 'mp4':
-                    height = int_or_none(media.get('quality'))
-                    formats.append({
-                        'url': video_url,
-                        'format_id': '%s-%d' % (format_id, height) if height else format_id,
-                        'height': height,
-                    })
-
-        self._remove_duplicate_formats(formats)
-
-        if not title:
-            title = self._search_regex(
-                (r'<h1>\s*(?P<title>[^<]+?)\s*</h1>', r'videoTitle\s*:\s*(["\'])(?P<title>.+?)\1'),
-                webpage, 'title', group='title')
-        description = self._og_search_description(
-            webpage, default=None) or self._html_search_meta(
-            'twitter:description', webpage, default=None) or self._search_regex(
-            r'</h1>\s*<p>([^<]+)', webpage, 'description', fatal=False)
-        uploader = self._search_regex(
-            (r'<input[^>]+name="contentOwnerId"[^>]+value="([^"]+)"',
-             r'<span[^>]+class="nickname"[^>]*>([^<]+)'),
-            webpage, 'uploader', fatal=False)
-        if not duration:
-            duration = parse_duration(self._search_regex(
-                r'<dt>Runtime:?</dt>\s*<dd>([^<]+)</dd>',
-                webpage, 'duration', fatal=False))
-        view_count = str_to_int(self._search_regex(
-            (r'["\']viewsCount["\'][^>]*>(\d+)\s+views',
-             r'<dt>Views:?</dt>\s*<dd>([\d,\.]+)</dd>'),
-            webpage, 'view count', fatal=False))
-        comment_count = str_to_int(self._html_search_regex(
-            r'>Comments? \(([\d,\.]+)\)<',
-            webpage, 'comment count', fatal=False))
-
-        return {
-            'id': video_id,
-            'display_id': display_id,
-            'title': title,
-            'description': description,
-            'thumbnail': thumbnail,
-            'uploader': uploader,
-            'duration': duration,
-            'view_count': view_count,
-            'comment_count': comment_count,
-            'age_limit': 18,
-            'formats': formats,
-        }
-
-
-class XTubeUserIE(InfoExtractor):
-    IE_DESC = 'XTube user profile'
-    _VALID_URL = r'https?://(?:www\.)?xtube\.com/profile/(?P<id>[^/]+-\d+)'
-    _TEST = {
-        'url': 'http://www.xtube.com/profile/greenshowers-4056496',
-        'info_dict': {
-            'id': 'greenshowers-4056496',
-            'age_limit': 18,
-        },
-        'playlist_mincount': 154,
-    }
-
-    def _real_extract(self, url):
-        user_id = self._match_id(url)
-
-        entries = []
-        for pagenum in itertools.count(1):
-            request = Request(
-                'http://www.xtube.com/profile/%s/videos/%d' % (user_id, pagenum),
-                headers={
-                    'Cookie': 'popunder=4',
-                    'X-Requested-With': 'XMLHttpRequest',
-                    'Referer': url,
-                })
-
-            page = self._download_json(
-                request, user_id, 'Downloading videos JSON page %d' % pagenum)
-
-            html = page.get('html')
-            if not html:
-                break
-
-            for video_id in orderedSet([video_id for _, video_id in re.findall(
-                    r'data-plid=(["\'])(.+?)\1', html)]):
-                entries.append(self.url_result('xtube:%s' % video_id, XTubeIE.ie_key()))
-
-            page_count = int_or_none(page.get('pageCount'))
-            if not page_count or pagenum == page_count:
-                break
-
-        playlist = self.playlist_result(entries, user_id)
-        playlist['age_limit'] = 18
-        return playlist
diff --git a/yt_dlp/extractor/xuite.py b/yt_dlp/extractor/xuite.py
deleted file mode 100644 (file)
index 71ddadd..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-from .common import InfoExtractor
-from ..utils import (
-    ExtractorError,
-    float_or_none,
-    get_element_by_attribute,
-    parse_iso8601,
-    remove_end,
-)
-
-
-class XuiteIE(InfoExtractor):
-    IE_DESC = '隨意窩Xuite影音'
-    _REGEX_BASE64 = r'(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?'
-    _VALID_URL = r'https?://vlog\.xuite\.net/(?:play|embed)/(?P<id>%s)' % _REGEX_BASE64
-    _TESTS = [{
-        # Audio
-        'url': 'http://vlog.xuite.net/play/RGkzc1ZULTM4NjA5MTQuZmx2',
-        'md5': 'e79284c87b371424885448d11f6398c8',
-        'info_dict': {
-            'id': '3860914',
-            'ext': 'mp3',
-            'title': '孤單南半球-歐德陽',
-            'description': '孤單南半球-歐德陽',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'duration': 247.246,
-            'timestamp': 1314932940,
-            'upload_date': '20110902',
-            'uploader': '阿能',
-            'uploader_id': '15973816',
-            'categories': ['個人短片'],
-        },
-    }, {
-        # Video with only one format
-        'url': 'http://vlog.xuite.net/play/WUxxR2xCLTI1OTI1MDk5LmZsdg==',
-        'md5': '21f7b39c009b5a4615b4463df6eb7a46',
-        'info_dict': {
-            'id': '25925099',
-            'ext': 'mp4',
-            'title': 'BigBuckBunny_320x180',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'duration': 596.458,
-            'timestamp': 1454242500,
-            'upload_date': '20160131',
-            'uploader': '屁姥',
-            'uploader_id': '12158353',
-            'categories': ['個人短片'],
-            'description': 'http://download.blender.org/peach/bigbuckbunny_movies/BigBuckBunny_320x180.mp4',
-        },
-    }, {
-        # Video with two formats
-        'url': 'http://vlog.xuite.net/play/bWo1N1pLLTIxMzAxMTcwLmZsdg==',
-        'md5': '1166e0f461efe55b62e26a2d2a68e6de',
-        'info_dict': {
-            'id': '21301170',
-            'ext': 'mp4',
-            'title': '暗殺教室 02',
-            'description': '字幕:【極影字幕社】',
-            'thumbnail': r're:^https?://.*\.jpg$',
-            'duration': 1384.907,
-            'timestamp': 1421481240,
-            'upload_date': '20150117',
-            'uploader': '我只是想認真點',
-            'uploader_id': '242127761',
-            'categories': ['電玩動漫'],
-        },
-        'skip': 'Video removed',
-    }, {
-        # Video with encoded media id
-        # from http://forgetfulbc.blogspot.com/2016/06/date.html
-        'url': 'http://vlog.xuite.net/embed/cE1xbENoLTI3NDQ3MzM2LmZsdg==?ar=0&as=0',
-        'info_dict': {
-            'id': '27447336',
-            'ext': 'mp4',
-            'title': '男女平權只是口號?專家解釋約會時男生是否該幫女生付錢 (中字)',
-            'description': 'md5:1223810fa123b179083a3aed53574706',
-            'timestamp': 1466160960,
-            'upload_date': '20160617',
-            'uploader': 'B.C. & Lowy',
-            'uploader_id': '232279340',
-        },
-    }, {
-        'url': 'http://vlog.xuite.net/play/S1dDUjdyLTMyOTc3NjcuZmx2/%E5%AD%AB%E7%87%95%E5%A7%BF-%E7%9C%BC%E6%B7%9A%E6%88%90%E8%A9%A9',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        # /play/ URLs provide embedded video URL and more metadata
-        url = url.replace('/embed/', '/play/')
-        video_id = self._match_id(url)
-
-        webpage = self._download_webpage(url, video_id)
-
-        error_msg = self._search_regex(
-            r'<div id="error-message-content">([^<]+)',
-            webpage, 'error message', default=None)
-        if error_msg:
-            raise ExtractorError(
-                '%s returned error: %s' % (self.IE_NAME, error_msg),
-                expected=True)
-
-        media_info = self._parse_json(self._search_regex(
-            r'var\s+mediaInfo\s*=\s*({.*});', webpage, 'media info'), video_id)
-
-        video_id = media_info['MEDIA_ID']
-
-        formats = []
-        for key in ('html5Url', 'html5HQUrl'):
-            video_url = media_info.get(key)
-            if not video_url:
-                continue
-            format_id = self._search_regex(
-                r'\bq=(.+?)\b', video_url, 'format id', default=None)
-            formats.append({
-                'url': video_url,
-                'ext': 'mp4' if format_id.isnumeric() else format_id,
-                'format_id': format_id,
-                'height': int(format_id) if format_id.isnumeric() else None,
-            })
-
-        timestamp = media_info.get('PUBLISH_DATETIME')
-        if timestamp:
-            timestamp = parse_iso8601(timestamp + ' +0800', ' ')
-
-        category = media_info.get('catName')
-        categories = [category] if category else []
-
-        uploader = media_info.get('NICKNAME')
-        uploader_url = None
-
-        author_div = get_element_by_attribute('itemprop', 'author', webpage)
-        if author_div:
-            uploader = uploader or self._html_search_meta('name', author_div)
-            uploader_url = self._html_search_regex(
-                r'<link[^>]+itemprop="url"[^>]+href="([^"]+)"', author_div,
-                'uploader URL', fatal=False)
-
-        return {
-            'id': video_id,
-            'title': media_info['TITLE'],
-            'description': remove_end(media_info.get('metaDesc'), ' (Xuite 影音)'),
-            'thumbnail': media_info.get('ogImageUrl'),
-            'timestamp': timestamp,
-            'uploader': uploader,
-            'uploader_id': media_info.get('MEMBER_ID'),
-            'uploader_url': uploader_url,
-            'duration': float_or_none(media_info.get('MEDIA_DURATION'), 1000000),
-            'categories': categories,
-            'formats': formats,
-        }
diff --git a/yt_dlp/extractor/yesjapan.py b/yt_dlp/extractor/yesjapan.py
deleted file mode 100644 (file)
index 94e4166..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-from .common import InfoExtractor
-from ..networking import HEADRequest
-from ..utils import get_element_by_attribute, parse_iso8601
-
-
-class YesJapanIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:www\.)?yesjapan\.com/video/(?P<slug>[A-Za-z0-9\-]*)_(?P<id>[A-Za-z0-9]+)\.html'
-    _TEST = {
-        'url': 'http://www.yesjapan.com/video/japanese-in-5-20-wa-and-ga-particle-usages_726497834.html',
-        'md5': 'f0be416314e5be21a12b499b330c21cf',
-        'info_dict': {
-            'id': '726497834',
-            'title': 'Japanese in 5! #20 - WA And GA Particle Usages',
-            'description': 'This should clear up some issues most students of Japanese encounter with WA and GA....',
-            'ext': 'mp4',
-            'timestamp': 1416391590,
-            'upload_date': '20141119',
-            'thumbnail': r're:^https?://.*\.jpg$',
-        }
-    }
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        webpage = self._download_webpage(url, video_id)
-        title = self._og_search_title(webpage)
-        video_url = self._og_search_video_url(webpage)
-        description = self._og_search_description(webpage)
-        thumbnail = self._og_search_thumbnail(webpage)
-
-        timestamp = None
-        submit_info = get_element_by_attribute('class', 'pm-submit-data', webpage)
-        if submit_info:
-            timestamp = parse_iso8601(self._search_regex(
-                r'datetime="([^"]+)"', submit_info, 'upload date', fatal=False, default=None))
-
-        # attempt to resolve the final URL in order to get a proper extension
-        redirect_req = HEADRequest(video_url)
-        req = self._request_webpage(
-            redirect_req, video_id, note='Resolving final URL', errnote='Could not resolve final URL', fatal=False)
-        if req:
-            video_url = req.url
-
-        formats = [{
-            'format_id': 'sd',
-            'url': video_url,
-        }]
-
-        return {
-            'id': video_id,
-            'title': title,
-            'formats': formats,
-            'description': description,
-            'timestamp': timestamp,
-            'thumbnail': thumbnail,
-        }
diff --git a/yt_dlp/extractor/yinyuetai.py b/yt_dlp/extractor/yinyuetai.py
deleted file mode 100644 (file)
index b2e3172..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-from .common import InfoExtractor
-from ..utils import ExtractorError
-
-
-class YinYueTaiIE(InfoExtractor):
-    IE_NAME = 'yinyuetai:video'
-    IE_DESC = '音悦Tai'
-    _VALID_URL = r'https?://v\.yinyuetai\.com/video(?:/h5)?/(?P<id>[0-9]+)'
-    _TESTS = [{
-        'url': 'http://v.yinyuetai.com/video/2322376',
-        'md5': '6e3abe28d38e3a54b591f9f040595ce0',
-        'info_dict': {
-            'id': '2322376',
-            'ext': 'mp4',
-            'title': '少女时代_PARTY_Music Video Teaser',
-            'creator': '少女时代',
-            'duration': 25,
-            'thumbnail': r're:^https?://.*\.jpg$',
-        },
-    }, {
-        'url': 'http://v.yinyuetai.com/video/h5/2322376',
-        'only_matching': True,
-    }]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-
-        info = self._download_json(
-            'http://ext.yinyuetai.com/main/get-h-mv-info?json=true&videoId=%s' % video_id, video_id,
-            'Downloading mv info')['videoInfo']['coreVideoInfo']
-
-        if info['error']:
-            raise ExtractorError(info['errorMsg'], expected=True)
-
-        formats = [{
-            'url': format_info['videoUrl'],
-            'format_id': format_info['qualityLevel'],
-            'format': format_info.get('qualityLevelName'),
-            'filesize': format_info.get('fileSize'),
-            # though URLs ends with .flv, the downloaded files are in fact mp4
-            'ext': 'mp4',
-            'tbr': format_info.get('bitrate'),
-        } for format_info in info['videoUrlModels']]
-
-        return {
-            'id': video_id,
-            'title': info['videoName'],
-            'thumbnail': info.get('bigHeadImage'),
-            'creator': info.get('artistNames'),
-            'duration': info.get('duration'),
-            'formats': formats,
-        }
diff --git a/yt_dlp/extractor/ynet.py b/yt_dlp/extractor/ynet.py
deleted file mode 100644 (file)
index a7d7371..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-import json
-import re
-import urllib.parse
-
-from .common import InfoExtractor
-
-
-class YnetIE(InfoExtractor):
-    _VALID_URL = r'https?://(?:.+?\.)?ynet\.co\.il/(?:.+?/)?0,7340,(?P<id>L(?:-[0-9]+)+),00\.html'
-    _TESTS = [
-        {
-            'url': 'http://hot.ynet.co.il/home/0,7340,L-11659-99244,00.html',
-            'info_dict': {
-                'id': 'L-11659-99244',
-                'ext': 'flv',
-                'title': 'איש לא יודע מאיפה באנו',
-                'thumbnail': r're:^https?://.*\.jpg',
-            }
-        }, {
-            'url': 'http://hot.ynet.co.il/home/0,7340,L-8859-84418,00.html',
-            'info_dict': {
-                'id': 'L-8859-84418',
-                'ext': 'flv',
-                'title': "צפו: הנשיקה הלוהטת של תורגי' ויוליה פלוטקין",
-                'thumbnail': r're:^https?://.*\.jpg',
-            }
-        }
-    ]
-
-    def _real_extract(self, url):
-        video_id = self._match_id(url)
-        webpage = self._download_webpage(url, video_id)
-
-        content = urllib.parse.unquote_plus(self._og_search_video_url(webpage))
-        config = json.loads(self._search_regex(r'config=({.+?})$', content, 'video config'))
-        f4m_url = config['clip']['url']
-        title = self._og_search_title(webpage)
-        m = re.search(r'ynet - HOT -- (["\']+)(?P<title>.+?)\1', title)
-        if m:
-            title = m.group('title')
-        formats = self._extract_f4m_formats(f4m_url, video_id)
-
-        return {
-            'id': video_id,
-            'title': title,
-            'formats': formats,
-            'thumbnail': self._og_search_thumbnail(webpage),
-        }