Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

watchcartoononline.com is not supported #1048

Closed
RavetcoFX opened this issue Jul 15, 2013 · 17 comments
Closed

watchcartoononline.com is not supported #1048

RavetcoFX opened this issue Jul 15, 2013 · 17 comments

Comments

@RavetcoFX
Copy link

@RavetcoFX RavetcoFX commented Jul 15, 2013

This site uses JW Player 5.10.2295, and is not supported by the generic downloader.

@phihag
Copy link
Contributor

@phihag phihag commented Jul 17, 2013

Can you post an example URL? Note that if possible, it should be SFW, and the content must not infringe copyright.

@RavetcoFX
Copy link
Author

@RavetcoFX RavetcoFX commented Jul 19, 2013

@phihag
Copy link
Contributor

@phihag phihag commented Jul 19, 2013

I'm pretty sure that the content at that URL infringes the copyright of the Cartoon Network; the official site makes no mention of it. We do cannot include extractors for sites that are used exclusively to host copyrighted content without permission. If you do think that we have added support for a "worse" site by accident, please name them and detail why their content is almost exclusively illegal in almost all jurisdictions.

@phihag phihag closed this Jul 19, 2013
@RavetcoFX
Copy link
Author

@RavetcoFX RavetcoFX commented Jul 20, 2013

All your adult sites
Anyway could you at least make it compatible with the generic downloader
Read this http://www.watchcartoononline.com/legal-disclaimer , it states:

"All Watchcartoononline.COM does is link or embed content that was uploaded to popular Online Video hosting sites like Veoh.com / Megavideo.com / Youtube.com / Google Video. All youtube/veoh/megavideo/googlevideo users signed a contract with the sites when they set up their accounts wich forces them not to upload illegal content. By clicking on any Links to videos while surfing on Watchcartoononline.COM you watch content hosted on third parties and Watchcartoononline.COM cant take the responsibility for any content hosted on other sites.

We do not upload any videos nor do we know who and where videos are coming from. We do not promote any illegal conduct of any kind. Links to the videos are submitted by users and managed by users."

@phihag
Copy link
Contributor

@phihag phihag commented Jul 20, 2013

First of all, I was under the impression that all of the adult sites we support contain a significant amount of user-generated content. I'm not aware that any our test videos there infringe copyright. Can you name a specific one? I'm pretty certain at least one is even Public Domain, since it is a PSA.

Can you name a single non-infringing URL at watchcartoononline.com? In any case, they can write all they want, but the video in question is hosted by watchanimesub.net, which is just another domain name of them.

@RavetcoFX
Copy link
Author

@RavetcoFX RavetcoFX commented Jul 21, 2013

Firstly you said things that are Safe for work, it seams you morals are mixed up, it should be you shouldn't support adult sites as those are nasty and should be made illegal, this is open source no? so there is no single person that can get sued or ect from downloading a episode except that website, so please can you support it as I watching it streamed is terrible with my Internet. Would you be able to send me a private patch or tell me how to do it

@phihag
Copy link
Contributor

@phihag phihag commented Jul 21, 2013

You misunderstand; I wrote

Note that if possible, it (the example URL) should be SFW, and the content must not infringe copyright.

So we'd like example URLs to be SFW (and actually, at least some of our porn sites do use example URLs that are SFW), but if not, that's fine too. On the other hand, the test suites are regularly run by the developers and travis, who could be liable for copyright infringement.

Adult content is legal in all developed countries (you write yourself * should be made illegal*), and I can't see a reason why it should be. Adult content being nasty does not mean it should illegal, but the opposite; freedom of speech is most necessary for things one finds nasty.

Yes, youtube-dl is open-source, and you or anyone else can publish a modified version with support for that site (although probably not on GitHub). But as software developers who rely on copyright (and only choose to use a liberal license) ourselves, we must insist on non-infringing content. Note that there are free-to-distribute cartoon videos. If watchcartoononline.com or any other site publishes these, we are more than happy to include support.

If there is not even a single non-infringing video on watchcartoononline, youtube-dl will not add support for it.

@RavetcoFX
Copy link
Author

@RavetcoFX RavetcoFX commented Jul 22, 2013

You yourself just wrote that we need freedom of speech, and posting a cartoon is freedom of speech, can you atleast tell me how to add support for my own local version.

@yasoob
Copy link
Contributor

@yasoob yasoob commented Jul 22, 2013

hey @phihag and @superfly1031 I think this discussion is going off the track. @superfly1031 we would really like to support it in youtube-dl but as phihag has mentioned there are licensing issues. If you really want to download cartoons from watchcartoononline then check out this script. I have made it specifically for you. However i was having a hard time integrating it in youtube-dl. You can use my script even if it's support is not added in youtube-dl due to licensing issues. If you encounter any issue with my script then feel free to open an issue on it's bug tracker.

@RavetcoFX
Copy link
Author

@RavetcoFX RavetcoFX commented Jul 23, 2013

@yasoob you're the best! Can I return the favor with a small donation?
You have made my life a little bit more perfect :)

@phihag
Copy link
Contributor

@phihag phihag commented Jul 23, 2013

Just for the record: Freedom of Speech protects your right to allow you to disseminate your content, and does not apply if you're disseminating something against the author's wishes.

@yasoob
Copy link
Contributor

@yasoob yasoob commented Jul 23, 2013

@superfly1031 I am happy that you liked it. However I am not ready for donations right now but will surely tell you when I am ;) .

@RavetcoFX
Copy link
Author

@RavetcoFX RavetcoFX commented Aug 9, 2016

Hey @phihag, I wanted to apologise for being such a dick, I was just reading this old thread and cringing from embarrassment, sorry for my past behaviour :/

@lvh88640
Copy link

@lvh88640 lvh88640 commented May 20, 2019

This is might be not legal website, But there are many websites where you can watch legally, Here are some popular websites for cartoon :-

  • Cartoon Network
  • Nickelodeon
  • DisneyNOW
  • NETFLIX

If you need more then read here for something more
thanks

@BiatuAutMiahn
Copy link

@BiatuAutMiahn BiatuAutMiahn commented Oct 27, 2019

@yasoob I tried this script to no avail, after modifying to access watchcartoonsonline.eu, and it failed again. A few days ago I tried for hours to manually download a stream, here are my finds:
They use hydrax for the movie im trying to download 'THE SEVENTH BROTHER (1991)'
First off, when activating the devtools in chrome the script page has javascript that will stall on the content debugger, you must disable breakpoints, then resume execution.

The actual video player iframe request is:

https://watchcartoonsonline.eu/wp-content/themes/magxp/movie/getlink.php?poster=&link=<EncodedLink, looks like mix of Base64 and uuencode or something else>

iframe src=

https://watchcartoonsonline.eu/hydapi.php?slug=<VideoID>

once the player starts an XHR request grabs the top level m3u8 playlist:

blob:https://watchcartoonsonline.eu/<some guid>
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=394000,RESOLUTION=480x360
blob:https://watchcartoonsonline.eu/<playlist guid>#<Some Base64 Key>
#EXT-X-STREAM-INF:BANDWIDTH=1998000,RESOLUTION=1280x720
blob:https://watchcartoonsonline.eu/<playlist guid>#<Some Base64 Key>

From there, another request is made:

blob:https://watchcartoonsonline.eu/<playlist guid>
#EXTM3U
#EXT-X-VERSION:4
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-TARGETDURATION:19
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-HASH:<AES-128 Hash?>
#EXTINF:19.486133,
https://i.yolande-cox.xyz/redirect/<contenlink>
#EXTINF:17.183833,
#EXT-X-BYTERANGE:982880@0
...
#EXT-X-ENDLIST

I managed to get streamlink to download the stream, however the contents are still encrypted.
I dug around the HLS streaming script to attempt to see how the key is derived, but the script was heavily obfuscated, the script seems to prefix "http://" to the EXT-X-HASH to the URI in EXT-X-KEY. and I manually derived the IV in a similar fashion to how the script does, however when trying to update the playlist with the proper EXT-X-KEY, streamlink failed with being unable to find the URI=http://<hash>, I imagine that the hash might be returning the same way the other resources are being loaded, ie: blob:...

Anyway I'm attempting to get this movie for a friend and it does not seems to exist ANYWHERE else that I could find after hours of digging elsewhere.

Edit:
I didn't have to authenticate, or accept any terms during the entire time I've been on that site. So the keys are public. And all I had to do to get streamlink to grab the video was to set the http header Origin: https://watchcartoonsonline.eu

Thank you

@BiatuAutMiahn
Copy link

@BiatuAutMiahn BiatuAutMiahn commented Oct 28, 2019

Turns out #EXT-X_HASH is the key, HLS loader converts the key to binary using btoa(hash). Wrote that to key.dat, and added #EXT-X-KEY to the m3u8 with IV (without last byte) and streamlink grabbed a ts file without issues.

The key changes by video, but it seems to stay the same over time for that video. It looks like the content is pre-encrypted on the google-based storage they're using. The IV didn't change across 2 different videos.

@BiatuAutMiahn
Copy link

@BiatuAutMiahn BiatuAutMiahn commented Oct 28, 2019

Finished prototype script in Python 3.8 that will extract the playlist and add in the #EXT-X-KEY info:

Note: this is not optimized, and it has poor error handling.

import pathlib
import json
import base64
import requests
import re
import string
import sys
import os

def pa(t,lo=0):
    ret={}
    e=t.copy()
    for s in ['servers','expired','sig','thumbnail','hash','id','ids','ping']:
        e.pop(s,None)
    if lo:
        return e
    for s in e:
        i,k,p=fa(e[s],t["servers"])
        ret[s]={'key':k,'iv':i,'playlist':p}
    return ret

def fa(t,e):
    n="#EXTM3U\n"
    n+="#EXT-X-VERSION:4\n"
    n+="#EXT-X-PLAYLIST-TYPE:VOD\n"
    n+="#EXT-X-TARGETDURATION:"+str(t['duration'])+"\n"
    n+="#EXT-X-MEDIA-SEQUENCE:0\n"
    n+="#EXT-X-HASH:"+t['hash']+"\n"
    key=base64.b64decode(t['hash']+'==')
    iv=t['iv']
    n+="#EXT-X-HASH:"+t['hash']+"\n"
    n+='#EXT-X-KEY:METHOD=AES-128,URI="key.dat",IV='+iv
    o=len(e)
    i=0
    r=0
    o=None
    if 'id' in t:
        o=t['id']
    a=None
    if 'id' in t:
        a=t['ids']
    s=None
    if 'expired' in t:
        s=t['expired']
    elif 'sig' in t:
        s=t['sig']
    c=None
    if 'datas' in t:
        c=t['datas']
    u=t['ranges']
    l=len(u)
    if c is not None:
        for h in u:
            f=None
            d=c[h]['file']
            for p in u[h]:
                y=None
                if l<=h+p+1:
                    if l<=p+1:
                        y=c[0]['file']
                    else:
                        y=c[p+1]['file']
                else:
                    y=c[h+p+1]['file']
                if i < o:
                    f=e[i]
                    i+=1
                else:
                    i=1,
                    f=e[0]
                a=u[h][p],
                f="https://"+f,
                n+="#EXTINF:"+t["extinfs"][r]+",\n"
                n+="#EXT-X-BYTERANGE:"+a+"\n",
                if s:
                    n+=(f+"/")+s+"/"+d+"/"+a+"/"+y+"\n"
                else:
                    n+=n+(f+"/")+r+"/"+d+"/"+a+"/"+y+"\n",
                r+=1
        n+="#EXT-X-ENDLIST"
    elif a:
        for ih,h in enumerate(u):
            d=a[ih]
            for ip,p in enumerate(h):
                y=None
                if l<=ih+ip+1:
                    if l<=ip+1:
                        y=a[0]
                    else:
                        y=a[ip+1]
                else:
                    y=a[ih + ip + 1]
                if isinstance(e["redirect"],list):
                    if i < len(e["redirect"]):
                        c = e["redirect"][i]
                        i+=1
                    else:
                        i=1
                        c=e["redirect"][0]
                else:
                    c = e["redirect"]
                n+="#EXTINF:"+t["extinfs"][r]+",\n"
                if 1 < len(h):
                    n+="#EXT-X-BYTERANGE:"+h[ip]+"\n"
                # print("https://%s/redirect/%s/%s/%s/%s"%(c,s,o,d,y))
                n+="https://"+c+"/redirect/"+s+"/"+o+"/"+d+"/"+y+"\n"
                r+=1;
        n+="#EXT-X-ENDLIST"
    return (iv,key,n)

def getStream(slug,apikey,stream=None):
    print("Retriving Playlist...")
    r = requests.post(url="https://multi.idocdn.com/vip",headers={"Content-Type": "application/x-www-form-urlencoded"},data="key="+apikey+"&type=slug&value="+slug)
    data=json.loads(r.text)
    if stream:
        if stream not in pa(data,1):
            print("Invalid Stream Type")
            exit()
        print("Generating Playlist...")
        data=pa(data)
        data=data[stream]
        print("Writing key.dat...")
        with open('key.dat','wb') as b:
            b.write(data["key"])
        print("Writing output.m3u8...")
        with open('output.m3u8','w') as b:
            b.write(data["playlist"])
    else:
        data=pa(data,1)
        print("Available Streams:")
        for s in data.keys():
            print(s)
        print('')
        exit()

if len(sys.argv)!=2 and len(sys.argv)!=3:
    print("Usage: "+sys.argv[0]+" https://watchcartoonsonline.eu/<Video> <Stream>")
    print("Note: Stream is listed when left blank.")
    exit()


print("Retriving URL...")
r = requests.get(sys.argv[1])
data=r.text.translate(str.maketrans('', '', string.whitespace))
search = re.compile(r".*{jQuery.ajax\({type:\"GET\",dataType:\"html\",url:\"(.*)\",data:{poster:\"(.*)\",link:\"([^\"]*)\"},.*")
match=search.match(data)
url,poster,link=match.groups()
print("Retriving Video Player...")
print((url,poster,link))
r = requests.get(url+"?poster="+poster+"&link="+link)
data=r.text.translate(str.maketrans('', '', string.whitespace))
search = re.compile(r".*\"(https://watchcartoonsonline\.eu/hydapi\.php\?slug=[^\"]*).*")
# print(data)
match=search.match(data)
url=''.join(match.groups())
# print(slug)
print("Retriving Video Info...")
r = requests.get(url,headers={"referer": sys.argv[1]+'/'})
data=r.text.translate(str.maketrans('', '',string.whitespace))
search = re.compile(r".*<script>newPlayer\({.*\"key\":\"([^\"]*)\",\"type\":\"([^\"]*)\",\"value\":\"([^\"]*)\".*}\);</script>.*")
match=search.match(data)
key,type,value=match.groups()
if type=='slug':
    if len(sys.argv)==3:
        getStream(value,key,sys.argv[2])
    else:
        getStream(value,key)
    print("Done.")
    print("Play it: streamlink --http-header origin=https://watchcartoonsonline.eu "+pathlib.Path(os.path.abspath('output.m3u8')).as_uri()+" best")
else:
    print("Invalid Stream Type")
exit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
6 participants
@phihag @RavetcoFX @yasoob @BiatuAutMiahn @lvh88640 and others
You can’t perform that action at this time.