A crunchyroll api integration in go with included cli

crunchyroll-go

A Go library & cli for the undocumented crunchyroll api.

You surely need a crunchyroll premium account to get full (api) access.

Code size License Go version Release

CLI 🖥️ Library 📚 Credits 🙏 License

🖥️ CLI

Features

  • Download single videos and entire series from crunchyroll

Get the executable

  • 📥 Download the latest binaries here or get it from below
  • 🛠 Build it yourself
    • use make (requires go to be installed)
    $ git clone https://github.com/ByteDream/crunchyroll-go
    $ cd crunchyroll-go
    $ make
    
    • use go
    $ git clone https://github.com/ByteDream/crunchyroll-go
    $ cd crunchyroll-go/cmd/crunchyroll-go
    $ go build -o crunchy
    

📝 Examples

Login

Before you can do something, you have to login first.

This can be performed via crunchyroll account email and password

$ crunchy login [email protected] password

or via session id

$ crunchy login --session-id 8e9gs135defhga790dvrf2i0eris8gts

Download

With the cli you can download single videos or entire series.

By default the cli tries to download the episode with your system language as audio. If no streams with your system language are available, the video will be downloaded with japanese audio and hardsubbed subtitles in your system language. If your system language is not supported, an error message will be displayed and en-US (american english) will be chosen as language.

$ crunchy download https://www.crunchyroll.com/darling-in-the-franxx/episode-1-alone-and-lonesome-759575

With -r best the video(s) will have the best available resolution (mostly 1920x1080 / Full HD).

$ crunchy download -r best https://www.crunchyroll.com/darling-in-the-franxx/episode-1-alone-and-lonesome-759575

The file is by default saved as a .ts (mpeg transport stream) file. .ts files may can't be played or are looking very weird (it depends on the video player you are using). With the -o flag, you can change the name (and file ending) of the output file. So if you want to save it as, for example, mp4 file, just name it whatever.mp4. You need ffmpeg to store the video in other file formats.

$ crunchy download -o "daaaaaaaaaaaaaaaarling.ts" https://www.crunchyroll.com/darling-in-the-franxx/episode-1-alone-and-lonesome-759575

With the --audio flag you can specify which audio the video should have and with --subtitle which subtitle it should have. Type crunchy help download to see all available locales.

$ crunchy download --audio ja-JP --subtitle de-DE https://www.crunchyroll.com/darling-in-the-franxx
Flags
  • --audio » forces audio of the video(s)

  • --subtitle » forces subtitle of the video(s)

  • --no-hardsub » forces that the subtitles are stored as a separate file and are not directly embedded into the video

  • -d, --directory » directory to download the video(s) to

  • -o, --output » name of the output file

  • -r, --resolution » the resolution of the video(s). best for best resolution, worst for worst

  • --alternative-progress » shows an alternative, not so user-friendly progress instead of the progress bar

Help

  • General help
    $ crunchy help
    
  • Login help
    $ crunchy help login
    
  • Download help
    $ crunchy help download
    

Global flags

These flags you can use across every sub-command

  • -q, --quiet » disables all output

  • -v, --verbote » shows additional debug output

  • --color » adds color to the output (works only on not windows systems)

  • -p, --proxy » use a proxy to hide your ip / redirect your traffic

  • -l, --locale » the language to display video specific things like the title. default is your system language

📚 Library

Download the library via go get

$ go get github.com/ByteDream/crunchyroll-go

📝 Examples

func main() {
    // login with credentials 
    crunchy, err := crunchyroll.LoginWithCredentials("[email protected]", "password", crunchyroll.US, http.DefaultClient)
    if err != nil {
        panic(err)
    }

    // finds a series or movie by a crunchyroll link
    video, err := crunchy.FindVideo("https://www.crunchyroll.com/darling-in-the-franxx")
    if err != nil {
        panic(err)
    }

    series := video.(*crunchyroll.Series)
    seasons, err := series.Seasons()
    if err != nil {
        panic(err)
    }
    fmt.Printf("Found %d seasons for series %s\n", len(seasons), series.Title)

    // search `Darling` and return 20 results
    series, movies, err := crunchy.Search("Darling", 20)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Found %d series and %d movies for query `Darling`\n", len(series), len(movies))
}
func main() {
    crunchy, err := crunchyroll.LoginWithSessionID("8e9gs135defhga790dvrf2i0eris8gts", crunchyroll.US, http.DefaultClient)
    if err != nil {
        panic(err)
    }

    // returns an episode slice with all episodes which are matching the given url.
    // the episodes in the returning slice differs from the underlying streams, but are all pointing to the first ditf episode
    episodes, err := crunchy.FindEpisode("https://www.crunchyroll.com/darling-in-the-franxx/episode-1-alone-and-lonesome-759575")
    if err != nil {
        panic(err)
    }
    fmt.Printf("Found %d episodes\n", len(episodes))
}

Structure

Because of the apis structure, it can lead very fast much redundant code for simple tasks, like getting all episodes with japanese audio and german subtitle. For this case and some other, the api has a utility called Structure in its utils.

func main() {
    crunchy, err := crunchyroll.LoginWithCredentials("[email protected]", "password", crunchyroll.US, http.DefaultClient)
    if err != nil {
        panic(err)
    }

    // search `Darling` and return 20 results (series and movies) or less
    series, movies, err := crunchy.Search("Darling", 20)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Found %d series and %d movies for search query `Darling`\n", len(series), len(movies))

    seasons, err := series[0].Seasons()
    if err != nil {
        panic(err)
    }

    // in the crunchyroll.utils package, you find some structs which can be used to simplify tasks.
    // you can recursively search all underlying content
    seriesStructure := utils.NewSeasonStructure(seasons)

    // this returns every format of all the above given seasons
    formats, err := seriesStructure.Formats()
    if err != nil {
        panic(err)
    }
    fmt.Printf("Found %d formats\n", len(formats))

    filteredFormats, err := seriesStructure.FilterFormatsByLocales(crunchyroll.JP, crunchyroll.DE, true)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Found %d formats with japanese audio and hardsubbed german subtitles\n", len(filteredFormats))

    // reverse sorts the formats after their resolution by calling a sort type which is also defined in the api utils
    // and stores the format with the highest resolution in a variable
    sort.Sort(sort.Reverse(utils.FormatsByResolution(filteredFormats)))
    format := formats[0]
    // get the episode from which the format is a child
    episode, err := seriesStructure.FilterEpisodeByFormat(format)
    if err != nil {
        panic(err)
    }

    file, err := os.Create(fmt.Sprintf("%s.ts", episode.Title))
    if err != nil {
        panic(err)
    }

    // download the format to the file
    if err := format.Download(file, nil); err != nil {
        panic(err)
    }
    fmt.Printf("Downloaded %s with %s resolution and %.2f fps as %s\n", episode.Title, format.Video.Resolution, format.Video.FPS, file.Name())

    // for more useful structure function just let your IDE's autocomplete make its thing
}

As you can see in the example above, most of the crunchyroll.utils Structure functions are returning errors. There is a build-in functionality with are avoiding causing the most errors and let you safely ignore them as well. Note that errors still can appear

func main() {
    crunchy, err := crunchyroll.LoginWithCredentials("[email protected]", "password", crunchyroll.US, http.DefaultClient)
    if err != nil {
        panic(err)
    }

    foundEpisodes, err := crunchy.FindEpisode("https://www.crunchyroll.com/darling-in-the-franxx/episode-1-alone-and-lonesome-759575")
    if err != nil {
    	panic(err)
    }
    episodeStructure := utils.NewEpisodeStructure(foundEpisodes)

    // this function recursively calls all api endpoints, receives everything and stores it in memory,
    // so that after executing this, no more request to the crunchyroll server has to be made.
    // note that it could cause much network load while running this method.
    //
    // you should check the InitAllState before, because InitAll could have been already called or
    // another function has the initialization as side effect and re-initializing everything
    // will change every pointer in the struct which can cause massive problems afterwards. 
    if !episodeStructure.InitAllState() {
        if err := episodeStructure.InitAll(); err != nil {
            panic(err)
        }
    }

    formats, _ := episodeStructure.Formats()
    streams, _ := episodeStructure.Streams()
    episodes, _ := episodeStructure.Episodes()
    fmt.Printf("Initialized %d formats, %d streams and %d episodes\n", len(formats), len(streams), len(episodes))
}

Tests

You can also run test to see if the api works correctly. Before doing this, make sure to either set your crunchyroll email and password or sessions as environment variable. The email variable has to be named EMAIL and the password variable PASSWORD. If you want to use your session id, the variable must be named SESSION_ID.

You can run the test via make

$ make test

or via go directly

$ go test .

🙏 Credits

Kamyroll-Python

  • Extracted all api endpoints and the login process from this

m3u8

  • Decrypting mpeg stream files

All libraries

  • m3u8 (not the m3u8 library from above) » mpeg stream info library
  • cobra » cli library

License

This project is licensed under the GNU Lesser General Public License v3.0 (LGPL-3.0) - see the LICENSE file for more details.

Owner
I'm a german student who loves open source development, to automate and simplify things
null
Similar Resources

Nebulant-cli - Nebulant's CLI

Nebulant-cli - Nebulant's CLI

Nebulant CLI Website: https://nebulant.io Documentation: https://nebulant.io/docs.html The Nebulant CLI tool is a single binary that can be used as a

Jan 11, 2022

News-parser-cli - Simple CLI which allows you to receive news depending on the parameters passed to it

News-parser-cli - Simple CLI which allows you to receive news depending on the parameters passed to it

news-parser-cli Simple CLI which allows you to receive news depending on the par

Jan 4, 2022

Nebula Diagnosis CLI Tool is an information diagnosis cli tool for the nebula service and the node to which the service belongs.

Nebula Diagnosis CLI Tool is an information diagnosis cli tool for the nebula service and the node to which the service belongs.

Jan 12, 2022

bcrypt-cli is the CLI tool for hashing passwords with bcrypt.

bcrypt-cli bcrypt-cli is the CLI tool for hashing passwords with bcrypt. Install go install github.com/ryicoh/bcrypt-cli Usage It can be used like bas

Jan 9, 2023

Gobby-cli - CLI application to debug gobby applications

go(bby) Interactive debugging tool for gobby applications Usage Coming soon™ Ins

Feb 8, 2022

GTDF-CLI - The official CLI tool to operate with Getting Things Done Framework

GTDF-CLI - The official CLI tool to operate with Getting Things Done Framework

This is the official CLI tool to operate with Getting Things Done Framework. How

Feb 14, 2022

Go pkg and cli tool to sign Google Maps API URLs

gmapsign gmapsign is a Go pkg and cli tool to sign Google Maps API request URLs. This is required when using: A client ID with the web service APIs, M

Jul 4, 2022

Simple CLI using spf13/cobra and Flink REST API

Flinkctl Flinkctl is a simple CLI written on Go using Cobra created to facilitate my team's daily basis work with multiple Flink clusters at Azion Tec

Aug 16, 2022

A simple CLI tool to use the _simulate API of elasticsearch to quickly test pipelines

elasticsearch-pipeline-tester A simple CLI tool to use the _simulate API of elasticsearch to quickly test pipelines usage: pipelinetester [flags] p

Oct 19, 2021
Comments
  • how to run

    how to run

    is there any instruction on how to use. i installed go but anytime i run any file i get "package command-line-arguments is not a main package" not sure what i am missing. any help or push in right direction would be appreciated

  • adding Chinese China (zh-CN ) as locale

    adding Chinese China (zh-CN ) as locale

    https://beta.crunchyroll.com/de/series/GZJH3DJ8E/the-daily-life-of-the-immortal-king

    Crunchyroll has recently added anime with the Chinese language. Therefore I have added the locale for it

    ➞ Downloading episode `Grande Dame vs Grande Dame` to `Grande Dame vs Grande Dame.mkv` (merging audio for additional formats)
    ➞       Episode: S03E01
    ➞       Audio: zh-CN
    ➞       Subtitle: 
    ➞       Resolution: 1920x1080px
    ➞       FPS: 24.00
    
    Audio
    ID                                       : 2
    Format                                   : AAC LC
    Format/Info                              : Advanced Audio Codec Low Complexity
    Codec-ID                                 : A_AAC-2
    Dauer                                    : 20 min 4s
    Kanäle                                   : 2 Kanäle
    Channel layout                           : L R
    Samplingrate                             : 44,1 kHz
    Bildwiederholungsrate                    : 43,066 FPS (1024 SPF)
    Compression mode                         : Lossy
    Titel                                    : Chinese China
    Sprache                                  : Chinesisch (CN)
    Default                                  : Nein
    Forced                                   : Nein
    
  • Better classic url parsing

    Better classic url parsing

    When parsing urls via *Crunchyroll.ParseUrl (and only with this function!), when the input is a classic url, it is checked if the url (when its get requested) has a Location header which points to its beta url equivalent.

    See crunchy-labs/crunchy-cli#22.

    This PR also removes the CLI stuff, I originally wanted to make this in a separate branch but eh forgot about that.

  • Add review endpoint

    Add review endpoint

    This PR adds the functionality to review a series and get review metadata from it like ratings.

    In the following, UserReview / userReview and OwnerReview / ownerReview are getting used. These are structs with the same fields but different methods. A review which was written by the logged-in account cannot be rated as helpful, and is therefore represented as a *OwnerReview which has only function to manipulate the review. A review written by another person on the other hand, has only functions to interact with it (rating as helpful, ...) and is represented as *UserReview.

    Rating

    Get the rating of a series.

    rating, err := series.Rating()
    

    Returns *crunchyroll.Rating.

    Reviews

    Get reviews of a series.

    // Sort the returning reviews by the newest first and filter them by reviews which has only one star
    options := crunchyroll.ReviewOptions {
        Sort: ReviewSortNewest,
        Filter: OneStar,
    }
    
    // Returns 5 reviews
    userReviews, err := series.Reviews(options, 1, 5)
    

    Returns crunchyroll.BulkResult[*crunchyroll.UserReview].

    CreateReview

    Create a review. Title must be 10 characters long or longer and content 100 charaters long or longer.

    title := "TestTestTest"
    content := "TestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTest"
    
    // Create a review with the given title and content and mark it as spoiler.
    ownerReview, err := series.CreateReview(title, content, true)
    

    Returns *crunchyroll.OwnerReview.

    GetOwnerReview

    Get the review from the logged-in account. Returns an error if none was written yet.

    ownerReview, err := series.GetOwnerReview()
    

    HasOwnerReview

    Returns if the logged-in account has written a review for the series.

    hasOwnerReview := series.HasOwnerReview()
    

    Rate

    Rate a series.

    err := series.Rate(FiveStars)
    

    Edit

    Edit your review.

    title := "TestTestTest1"
    content := "TestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTestTest1"
    
    // Edit the review with the given title and content and not mark it as spoiler.
    err := ownerReview.Edit(title, content, false)
    

    Delete

    Delete your review.

    err := ownerReview.Delete()
    

    RateHelpful

    Rate a review as helpul. A review can only be rated once as helpful (or not helpful) and this cannot be undone, so be careful. Check UserReview.Rated() if the review is already rated.

    err := userReview.RateHelpful()
    

    RateNotHelpful

    Rate a review as not helpul. A review can only be rated once as not helpful (or helpful) and this cannot be undone, so be careful. Check UserReview.Rated() if the review is already rated.

    err := userReview.RateNotHelpful()
    

    Rated

    Check if a review is already rated.

    rated := userReview.Rated()
    

    Report

    Report a review. Check for Review.Ratings.Reported if the review is reported. If this is the case, the function will fail.

    err := review.Report()
    

    RemoveReport

    Remove a report from a review. Check for Review.Ratings.Reported if the review is reported. If this is not the case, the function will fail.

    err := review.RemoveReport()
    
Go-api-cli - Small CLI to fetch data from an API sync and async

Async API Cli CLI to fetch data on "todos" from a given API in a number of ways.

Jan 13, 2022
Test-app-url-shortner - A sample url shortener app to test Keploy integration capabilities
Test-app-url-shortner - A sample url shortener app to test Keploy integration capabilities

test-app-url-shortner A sample url shortener app to test Keploy integration capa

Jan 23, 2022
Syno-cli - Synology unofficial API CLI and library

Synology CLI Unofficial wrapper over Synology API in Go. Focus on administrative

Jan 6, 2023
Elegant CLI wrapper for kubeseal CLI

Overview This is a wrapper CLI ofkubeseal CLI, specifically the raw mode. If you just need to encrypt your secret on RAW mode, this CLI will be the ea

Jan 8, 2022
CLI to run a docker image with R. CLI built using cobra library in go.
CLI  to run a docker image with R. CLI built using cobra library in go.

BlueBeak Installation Guide Task 1: Building the CLI The directory structure looks like Fastest process: 1)cd into bbtools 2)cd into bbtools/bin 3)I h

Dec 20, 2021
A wrapper of aliyun-cli subcommand alidns, run aliyun-cli in Declarative mode.

aliyun-dns A wrapper of aliyun-cli subcommand alidns, run aliyun-cli in Declarative mode. Installation Install aliyun-cli. Usage $ aliyun-dns -h A wra

Dec 21, 2021
Symfony-cli - The Symfony CLI tool For Golang

Symfony CLI Install To install Symfony CLI, please download the appropriate vers

Dec 28, 2022
Go-file-downloader-ftctl - A file downloader cli built using golang. Makes use of cobra for building the cli and go concurrent feature to download files.

ftctl This is a file downloader cli written in Golang which uses the concurrent feature of go to download files. The cli is built using cobra. How to

Jan 2, 2022
Cli-algorithm - A cli program with A&DS in go!

cli-algorithm Objectives The objective of this cli is to implement 4 basic algorithms to sort arrays been Merge Sort Insertion Sort Bubble Sort Quick

Jan 2, 2022