Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7145f72635 | ||
|
|
4f613ad45c | ||
|
|
1afcef88a0 | ||
|
|
1288d0b3f8 | ||
|
|
2bb5feb647 | ||
|
|
602f772fcf | ||
|
|
887b3ed094 | ||
|
|
49e3290f28 | ||
|
|
5d32d91d7d | ||
|
|
2f1858cde7 | ||
|
|
a98ed223c6 | ||
|
|
575569bd91 | ||
|
|
44a66286cb | ||
|
|
eb7de600c1 | ||
|
|
d2e8a4c02e |
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,8 +1,3 @@
|
||||
dist/
|
||||
node_modules/
|
||||
obj/
|
||||
typings/
|
||||
*.dat
|
||||
*.dll
|
||||
*.suo
|
||||
*.tmp
|
||||
12
.npmignore
12
.npmignore
@@ -1,16 +1,8 @@
|
||||
extras/
|
||||
node_modules/
|
||||
obj/
|
||||
src/
|
||||
typings/
|
||||
*.dat
|
||||
*.DotSettings
|
||||
*.dll
|
||||
*.map
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.suo
|
||||
*.tmp
|
||||
ts.js
|
||||
tsconfig.json
|
||||
tsd.json
|
||||
tslint.json
|
||||
tslint.json
|
||||
|
||||
154
README.md
154
README.md
@@ -1,69 +1,117 @@
|
||||
# CrunchyRoll.js
|
||||
|
||||
*CrunchyRoll.js* is capable of downloading *anime* episodes from the popular
|
||||
*CrunchyRoll* streaming service. An episode is stored in the original video format
|
||||
(often H.264 in a MP4 container) and the configured subtitle format (ASS or
|
||||
SRT).The two output files are then merged into a single MKV file.
|
||||
*CrunchyRoll.js* is capable of downloading *anime* episodes from the popular *CrunchyRoll* streaming service. An episode is stored in the original video format (often H.264 in a MP4 container) and the configured subtitle format (ASS or SRT).The two output files are then merged into a single MKV file.
|
||||
|
||||
## Motivation
|
||||
|
||||
*CrunchyRoll* has been providing an amazing streaming service and offers the
|
||||
best way to enjoy *anime* in a *convenient* and *legal* way. As a streaming
|
||||
service, video files cannot be downloaded and watched offline. Understandable
|
||||
from a business perspective and considering possible contract implications, but
|
||||
annoying for users. This application enables episodes to be downloaded for
|
||||
offline convenience. Please do not abuse this application; download episodes for
|
||||
**personal use** and **delete them** if you do not have an active premium
|
||||
account. Continue to support *CrunchyRoll*; without our financial backing their
|
||||
service cannot exist!
|
||||
*CrunchyRoll* has been providing an amazing streaming service and offers the best way to enjoy *anime* in a *convenient* and *legal* way. As a streaming service, video files cannot be downloaded and watched offline. Understandable from a business perspective and considering possible contract implications, but annoying for users. This application enables episodes to be downloaded for offline convenience. Please do not abuse this application; download episodes for **personal use** and **delete them** if you do not have an active premium account. Continue to support *CrunchyRoll*; without our financial backing their service cannot exist!
|
||||
|
||||
## Legal Warning
|
||||
|
||||
This application is not endorsed or affliated with *CrunchyRoll*. The usage of
|
||||
this application enables episodes to be downloaded for offline convenience which
|
||||
may be forbidden by law in your country. Usage of this application may also
|
||||
cause a violation of the agreed *Terms of Service* between you and the stream
|
||||
provider. A tool is not responsible for your actions; please make an informed
|
||||
decision prior to using this application.
|
||||
|
||||
## Status
|
||||
|
||||
### Implemented
|
||||
|
||||
* Subtitle decoding.
|
||||
* Subtitle converter for SRT subtitle output.
|
||||
* Video streaming.
|
||||
* Episode page scraping with subtitle saving and video streaming.
|
||||
* Add ASS support.
|
||||
* Add muxing (MP4+ASS=MKV).
|
||||
* Add series API to save an entire series rather than per-episode.
|
||||
* Add support for incremental saves.
|
||||
* Add batch-mode to queue a bunch of series.
|
||||
* Add CLI interface with all the options.
|
||||
* Support scheduled merging; if it fails now, the video is probably being watched.
|
||||
* Add authentication to the entire stack to support premium content.
|
||||
* Binary runner for `npm`
|
||||
* Windows examples with a .bat for ease of use.
|
||||
* Publish to `npm` with a fixed package.json.
|
||||
* Conversion to beautiful TypeScript 1.4 code.
|
||||
|
||||
### Pending Implementation
|
||||
|
||||
* Documentation.
|
||||
* Enjoy beautiful anime series from disk when internet is down.
|
||||
This application is not endorsed or affliated with *CrunchyRoll*. The usage of this application enables episodes to be downloaded for offline convenience which may be forbidden by law in your country. Usage of this application may also cause a violation of the agreed *Terms of Service* between you and the stream provider. A tool is not responsible for your actions; please make an informed decision prior to using this application.
|
||||
|
||||
## Configuration
|
||||
|
||||
Set defaults in https://www.crunchyroll.com/acct/?action=video. We'll use that.
|
||||
It is recommended to enable authentication (`-p` and `-u`) so your account permissions and settings are available for use. It is not possible to download non-free material without an account and premium subscription. Furthermore, the default account settings are used when downloading. If you want the highest quality videos, configure these preferences at https://www.crunchyroll.com/acct/?action=video.
|
||||
|
||||
|
||||
## Prerequisites
|
||||
|
||||
* NodeJS >= 0.12.x (http://nodejs.org/)
|
||||
* NPM >= 2.5.x (https://www.npmjs.org/)
|
||||
|
||||
## Installation
|
||||
|
||||
Use the applicable instructions to install. Is your operating system not listed? Please ask or contribute!
|
||||
|
||||
### Debian (Mint, Ubuntu, etc)
|
||||
|
||||
1. Run in *Terminal*: `sudo apt-get install nodejs npm mkvtoolnix rtmpdump`
|
||||
2. Run in *Terminal*: `sudo ln -s /usr/bin/nodejs /usr/bin/node`
|
||||
3. Run in *Terminal*: `sudo npm install -g crunchyroll`
|
||||
|
||||
### Mac OS X
|
||||
|
||||
1. Install *Homebrew* following the instructions at http://brew.sh/
|
||||
2. Run in *Terminal*: `brew install node mkvtoolnix rtmpdump`
|
||||
3. Run in *Terminal*: `npm install -g crunchyroll`
|
||||
|
||||
### Windows
|
||||
|
||||
1. Install *NodeJS* following the instructions at http://nodejs.org/
|
||||
3. Run in *Command Prompt*: `npm install -g crunchyroll`
|
||||
|
||||
## Instructions
|
||||
|
||||
Use the applicable instructions for the interface of your choice (currently limited to command-line).
|
||||
|
||||
### Command-line Interface (`crunchyroll`)
|
||||
|
||||
The [command-line interface](http://en.wikipedia.org/wiki/Command-line_interface) does not have a graphical component and is ideal for automation purposes and headless machines. The interface can run using a sequence of series addresses (the site address containing the episode listing), or with a batch-mode source file. The `crunchyroll --help` command will produce the following output:
|
||||
|
||||
Usage: crunchyroll [options]
|
||||
|
||||
Options:
|
||||
|
||||
-h, --help output usage information
|
||||
-V, --version output the version number
|
||||
-p, --pass <s> The password.
|
||||
-u, --user <s> The e-mail address or username.
|
||||
-c, --cache Disables the cache.
|
||||
-m, --merge Disables merging subtitles and videos.
|
||||
-e, --episode <i> The episode filter.
|
||||
-v, --volume <i> The volume filter.
|
||||
-f, --format <s> The subtitle format. (Default: ass)
|
||||
-o, --output <s> The output path.
|
||||
-s, --series <s> The series override.
|
||||
-t, --tag <s> The subgroup. (Default: CrunchyRoll)
|
||||
|
||||
#### Batch-mode
|
||||
|
||||
When no sequence of series addresses is provided, the batch-mode source file will be read (which is *CrunchyRoll.txt* in the current work directory. Each line in this file is processed as a seperate command-line statement. This makes it ideal to manage a large sequence of series addresses with variating command-line options or incremental episode updates.
|
||||
|
||||
#### Examples
|
||||
|
||||
Download in batch-mode:
|
||||
|
||||
crunchyroll
|
||||
|
||||
Download *Fairy Tail* to the current work directory:
|
||||
|
||||
crunchyroll http://www.crunchyroll.com/fairy-tail
|
||||
|
||||
Download *Fairy Tail* to `C:\Anime`:
|
||||
|
||||
crunchyroll --output C:\Anime http://www.crunchyroll.com/fairy-tail
|
||||
|
||||
#### Switches
|
||||
|
||||
##### Authentication
|
||||
|
||||
* `-p or --pass <s>` sets the password.
|
||||
* `-u or --user <s>` sets the e-mail address or username.
|
||||
|
||||
##### Disables
|
||||
|
||||
* `-c or --cache` disables the cache.
|
||||
* `-m or --merge` disables merging subtitles and videos.
|
||||
|
||||
##### Filters
|
||||
|
||||
* `-e or --episode <i>` filters episodes (positive is greater than, negative is smaller than).
|
||||
* `-v or --volume <i>` filters volumes (positive is greater than, negative is smaller than).
|
||||
|
||||
##### Settings
|
||||
|
||||
* `-f or --format <s>` sets the subtitle format. (Default: ass)
|
||||
* `-o or --output <s>` sets the output path.
|
||||
* `-s or --series <s>` sets the series override.
|
||||
* `-t or --tag <s>` sets The subgroup. (Default: CrunchyRoll)
|
||||
|
||||
## Developers
|
||||
|
||||
* Visual Studio 2013 Update 4 (Core)
|
||||
* NodeJS Tools (Debugging)
|
||||
* TypeScript 1.4 (Language)
|
||||
* ReSharper 9.0+ (Hints/Formatting)
|
||||
* Web Essentials (TSLint)
|
||||
More information will be added at a later point. For now the recommendations are:
|
||||
|
||||
## Work In Progress
|
||||
* Atom with `atom-typescript` and `linter-tslint` (and dependencies).
|
||||
|
||||
Open an issue or e-mail me directly. I'd be happy to answer your questions.
|
||||
Since this project uses TypeScript, compile with `node ts` or `npm install`.
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<EnableTypeScript>True</EnableTypeScript>
|
||||
<OutputPath>.</OutputPath>
|
||||
<ProjectGuid>{c5cff68a-d733-4347-83e7-6e5fe58eb0e3}</ProjectGuid>
|
||||
<ProjectHome />
|
||||
<ProjectTypeGuids>{3AF33F2E-1136-4D97-BBB7-1795711AC8B8};{349c5851-65df-11da-9384-00065b846f21};{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}</ProjectTypeGuids>
|
||||
<ProjectView>ShowAllFiles</ProjectView>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<StartupFile>cli.ts</StartupFile>
|
||||
<TypeScriptModuleKind>CommonJS</TypeScriptModuleKind>
|
||||
<TypeScriptNoImplicitAny>True</TypeScriptNoImplicitAny>
|
||||
<TypeScriptOutDir>dist</TypeScriptOutDir>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">11.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
<WorkingDirectory>.</WorkingDirectory>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
|
||||
<TypeScriptSourceMap>True</TypeScriptSourceMap>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<TypeScriptGeneratesDeclarations>True</TypeScriptGeneratesDeclarations>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<TypeScriptCompile Include="src\cli.ts" />
|
||||
<TypeScriptCompile Include="src\batch.ts" />
|
||||
<TypeScriptCompile Include="src\episode.ts" />
|
||||
<TypeScriptCompile Include="src\index.ts" />
|
||||
<TypeScriptCompile Include="src\request.ts" />
|
||||
<TypeScriptCompile Include="src\series.ts" />
|
||||
<TypeScriptCompile Include="src\subtitle\decode.ts" />
|
||||
<TypeScriptCompile Include="src\subtitle\formats\ass.ts" />
|
||||
<TypeScriptCompile Include="src\subtitle\formats\index.ts" />
|
||||
<TypeScriptCompile Include="src\subtitle\formats\srt.ts" />
|
||||
<TypeScriptCompile Include="src\subtitle\index.ts" />
|
||||
<TypeScriptCompile Include="src\typings.ts" />
|
||||
<TypeScriptCompile Include="src\video\index.ts" />
|
||||
<TypeScriptCompile Include="src\video\merge.ts" />
|
||||
<TypeScriptCompile Include="src\video\stream.ts" />
|
||||
<TypeScriptCompile Include="typings\big-integer\big-integer.d.ts" />
|
||||
<TypeScriptCompile Include="typings\cheerio\cheerio.d.ts" />
|
||||
<TypeScriptCompile Include="typings\commander\commander.d.ts" />
|
||||
<TypeScriptCompile Include="typings\form-data\form-data.d.ts" />
|
||||
<TypeScriptCompile Include="typings\mkdirp\mkdirp.d.ts" />
|
||||
<TypeScriptCompile Include="typings\node\node.d.ts" />
|
||||
<TypeScriptCompile Include="typings\request\request.d.ts" />
|
||||
<TypeScriptCompile Include="typings\xml2js\xml2js.d.ts" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="src\" />
|
||||
<Folder Include="src\subtitle\" />
|
||||
<Folder Include="src\subtitle\formats\" />
|
||||
<Folder Include="src\video\" />
|
||||
<Folder Include="typings" />
|
||||
<Folder Include="typings\big-integer\" />
|
||||
<Folder Include="typings\cheerio\" />
|
||||
<Folder Include="typings\commander\" />
|
||||
<Folder Include="typings\form-data\" />
|
||||
<Folder Include="typings\mkdirp\" />
|
||||
<Folder Include="typings\node" />
|
||||
<Folder Include="typings\request\" />
|
||||
<Folder Include="typings\xml2js\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.Common.targets" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" Condition="False" />
|
||||
<Import Project="$(VSToolsPath)\Node.js Tools\Microsoft.NodejsTools.targets" />
|
||||
<ProjectExtensions>
|
||||
<VisualStudio>
|
||||
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
|
||||
<WebProjectProperties>
|
||||
<AutoAssignPort>True</AutoAssignPort>
|
||||
<CustomServerUrl>http://localhost:1337</CustomServerUrl>
|
||||
<DevelopmentServerPort>0</DevelopmentServerPort>
|
||||
<DevelopmentServerVPath>/</DevelopmentServerVPath>
|
||||
<IISUrl>http://localhost:48022/</IISUrl>
|
||||
<NTLMAuthentication>False</NTLMAuthentication>
|
||||
<SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
|
||||
<UseCustomServer>True</UseCustomServer>
|
||||
<UseIIS>False</UseIIS>
|
||||
</WebProjectProperties>
|
||||
</FlavorProperties>
|
||||
<FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}" User="">
|
||||
<WebProjectProperties>
|
||||
<AlwaysStartWebServerOnDebug>False</AlwaysStartWebServerOnDebug>
|
||||
<AspNetDebugging>True</AspNetDebugging>
|
||||
<EnableENC>False</EnableENC>
|
||||
<ExternalProgram />
|
||||
<NativeDebugging>False</NativeDebugging>
|
||||
<SilverlightDebugging>False</SilverlightDebugging>
|
||||
<SQLDebugging>False</SQLDebugging>
|
||||
<StartAction>CurrentPage</StartAction>
|
||||
<StartCmdLineArguments />
|
||||
<StartExternalURL />
|
||||
<StartPageUrl />
|
||||
<StartWorkingDirectory />
|
||||
</WebProjectProperties>
|
||||
</FlavorProperties>
|
||||
</VisualStudio>
|
||||
</ProjectExtensions>
|
||||
</Project>
|
||||
@@ -1,22 +0,0 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 2013
|
||||
VisualStudioVersion = 12.0.31101.0
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9092AA53-FB77-4645-B42D-1CCCA6BD08BD}") = "crunchyroll.js", "crunchyroll.js.njsproj", "{C5CFF68A-D733-4347-83E7-6E5FE58EB0E3}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{C5CFF68A-D733-4347-83E7-6E5FE58EB0E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C5CFF68A-D733-4347-83E7-6E5FE58EB0E3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C5CFF68A-D733-4347-83E7-6E5FE58EB0E3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C5CFF68A-D733-4347-83E7-6E5FE58EB0E3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
@@ -1,65 +0,0 @@
|
||||
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
|
||||
<s:String x:Key="/Default/CodeEditing/Intellisense/CodeCompletion/IntellisenseGloballyEnabled/IntellisenseEnabled/@EntryValue">Disabled</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=DeclarationHides/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=InconsistentNaming/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=NotAllPathsReturnValue/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=RedundantQualifier/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||
|
||||
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SpecifyVariableTypeExplicitly/@EntryIndexedValue">DO_NOT_SHOW</s:String>
|
||||
<s:String x:Key="/Default/CodeInspection/TypeScriptInspections/Level/@EntryValue">TypeScript14</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/Profiles/=TypeScript/@EntryIndexedValue"><?xml version="1.0" encoding="utf-16"?><Profile name="TypeScript"><FormatAttributeQuoteDescriptor>True</FormatAttributeQuoteDescriptor><JsReformatCode>True</JsReformatCode><JsFormatDocComments>True</JsFormatDocComments><JsInsertSemicolon>True</JsInsertSemicolon><RemoveRedundantQualifiersTs>True</RemoveRedundantQualifiersTs><OptimizeImportsTs>True</OptimizeImportsTs><OptimizeReferenceCommentsTs>True</OptimizeReferenceCommentsTs><PublicModifierStyleTs>True</PublicModifierStyleTs><RelativePathStyleTs>True</RelativePathStyleTs><TypeAnnotationStyleTs>True</TypeAnnotationStyleTs></Profile></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeCleanup/SilentCleanupProfile/@EntryValue">TypeScript</s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/FORCE_CONTROL_STATEMENTS_BRACES/@EntryValue">ONLY_FOR_MULTILINE</s:String>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/KEEP_BLANK_LINES_BETWEEN_DECLARATIONS/@EntryValue">1</s:Int64>
|
||||
<s:Int64 x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/KEEP_BLANK_LINES_IN_CODE/@EntryValue">1</s:Int64>
|
||||
<s:String x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/QUOTE_STYLE/@EntryValue">SingleQuoted</s:String>
|
||||
|
||||
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/SPACE_WITHIN_OBJECT_LITERAL_BRACES/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/JavaScriptCodeFormatting/STICK_COMMENT/@EntryValue">False</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FBLOCK_005FSCOPE_005FCONSTANT/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FBLOCK_005FSCOPE_005FVARIABLE/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FCONSTRUCTOR/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FFUNCTION/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FGLOBAL_005FVARIABLE/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FLABEL/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FLOCAL_005FVARIABLE/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FOBJECT_005FPROPERTY_005FOF_005FFUNCTION/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=JS_005FPARAMETER/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FCLASS/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FENUM/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FENUM_005FMEMBER/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FINTERFACE/@EntryIndexedValue"><Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FINTERFACE_005FFOR_005FJS_005FGLOBAL_005FVARIABLE/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FMODULE/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FMODULE_005FEXPORTED/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FMODULE_005FLOCAL/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPRIVATE_005FMEMBER_005FACCESSOR/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPRIVATE_005FSTATIC_005FTYPE_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPRIVATE_005FTYPE_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPRIVATE_005FTYPE_005FMETHOD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPROTECTED_005FMEMBER_005FACCESSOR/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPROTECTED_005FSTATIC_005FTYPE_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPROTECTED_005FTYPE_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPROTECTED_005FTYPE_005FMETHOD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPUBLIC_005FMEMBER_005FACCESSOR/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPUBLIC_005FSTATIC_005FTYPE_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPUBLIC_005FTYPE_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FPUBLIC_005FTYPE_005FMETHOD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/JavaScriptNaming/UserRules/=TS_005FTYPE_005FPARAMETER/@EntryIndexedValue"><Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FHTML_005FCONTROL/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FTAG_005FNAME/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/WebNaming/UserRules/=ASP_005FTAG_005FPREFIX/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=NAMESPACE_005FALIAS/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=XAML_005FFIELD/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=XAML_005FRESOURCE/@EntryIndexedValue"><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/TypeScriptCodeStyle/ExplicitPublicModifier/@EntryValue">True</s:Boolean>
|
||||
<s:String x:Key="/Default/CodeStyle/TypeScriptCodeStyle/FileReferenceStyle/@EntryValue">RelativeDotSlash</s:String>
|
||||
<s:Boolean x:Key="/Default/CodeStyle/TypeScriptCodeStyle/NoImplicitAny/@EntryValue">True</s:Boolean>
|
||||
|
||||
<s:Boolean x:Key="/Default/CodeStyle/TypeScriptCodeStyle/PreferUsingAliases/@EntryValue">False</s:Boolean>
|
||||
<s:Boolean x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=AAA631615CEE9646AA8766F222F9457C/@KeyIndexDefined">True</s:Boolean>
|
||||
<s:String x:Key="/Default/Environment/InjectedLayers/FileInjectedLayer/=AAA631615CEE9646AA8766F222F9457C/AbsolutePath/@EntryValue">C:\Dropbox\Github\crunchyroll.js\crunchyroll.js.sln.DotSettings</s:String>
|
||||
<s:Boolean x:Key="/Default/Environment/InjectedLayers/InjectedLayerCustomization/=FileAAA631615CEE9646AA8766F222F9457C/@KeyIndexDefined">True</s:Boolean>
|
||||
<s:Double x:Key="/Default/Environment/InjectedLayers/InjectedLayerCustomization/=FileAAA631615CEE9646AA8766F222F9457C/RelativePriority/@EntryValue">1</s:Double></wpf:ResourceDictionary>
|
||||
12
package.json
12
package.json
@@ -11,26 +11,26 @@
|
||||
"type": "git",
|
||||
"url": "git://github.com/Deathspike/crunchyroll.js.git"
|
||||
},
|
||||
"version": "1.1.0",
|
||||
"version": "1.1.3",
|
||||
"bin": {
|
||||
"crunchyroll": "./bin/crunchyroll"
|
||||
},
|
||||
"dependencies": {
|
||||
"big-integer": "^1.4.3",
|
||||
"big-integer": "^1.4.4",
|
||||
"cheerio": "^0.18.0",
|
||||
"commander": "^2.6.0",
|
||||
"mkdirp": "^0.5.0",
|
||||
"request": "^2.53.0",
|
||||
"xml2js": "^0.4.4"
|
||||
"xml2js": "^0.4.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"tsd": "^0.5.7",
|
||||
"tslint": "^2.1.0",
|
||||
"tslint": "^2.1.1",
|
||||
"typescript": "^1.4.1"
|
||||
},
|
||||
"scripts": {
|
||||
"prepublish": "npm run tsd && node ts",
|
||||
"test": "node ts --only-test",
|
||||
"tsd": "./node_modules/.bin/tsd reinstall --overwrite"
|
||||
"tsd": "tsd reinstall --overwrite"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,4 +92,4 @@ function parse(args: string[]): typings.IConfigLine {
|
||||
.option('-s, --series <s>', 'The series override.')
|
||||
.option('-t, --tag <s>', 'The subgroup. (Default: CrunchyRoll)')
|
||||
.parse(args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,4 +3,4 @@ import batch = require('./batch');
|
||||
|
||||
batch(process.argv, (err: any) => {
|
||||
if (err) console.error(err.stack || err);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,7 +51,8 @@ function download(config: typings.IConfig, page: typings.IEpisodePage, player: t
|
||||
downloadVideo(config, page, player, filePath, err => {
|
||||
if (err) return done(err);
|
||||
if (config.merge) return complete('Finished ' + fileName, now, done);
|
||||
video.merge(config, player.video.file, filePath, err => {
|
||||
var isSubtited = Boolean(player.subtitle);
|
||||
video.merge(config, isSubtited, player.video.file, filePath, err => {
|
||||
if (err) return done(err);
|
||||
complete('Finished ' + fileName, now, done);
|
||||
});
|
||||
@@ -63,8 +64,9 @@ function download(config: typings.IConfig, page: typings.IEpisodePage, player: t
|
||||
/**
|
||||
* Saves the subtitles to disk.
|
||||
*/
|
||||
function downloadSubtitle(config: typings.IConfig, player: typings.IEpisodePlayer, filePath: string, done: (err: Error) => void) {
|
||||
function downloadSubtitle(config: typings.IConfig, player: typings.IEpisodePlayer, filePath: string, done: (err?: Error) => void) {
|
||||
var enc = player.subtitle;
|
||||
if (!enc) return done();
|
||||
subtitle.decode(enc.id, enc.iv, enc.data, (err, data) => {
|
||||
if (err) return done(err);
|
||||
var formats = subtitle.formats;
|
||||
@@ -121,7 +123,7 @@ function scrapePage(config: typings.IConfig, address: string, done: (err: Error,
|
||||
if (err) return done(err);
|
||||
var $ = cheerio.load(result);
|
||||
var swf = /^([^?]+)/.exec($('link[rel=video_src]').attr('href'));
|
||||
var regexp = /Watch\s+(.+?)(?:\s+Season\s+([0-9]+))?\s+Episode\s+([0-9]+)/;
|
||||
var regexp = /-\s+(?:Watch\s+)?(.+?)(?:\s+Season\s+([0-9]+))?(?:\s+-)?\s+Episode\s+([0-9]+)/;
|
||||
var data = regexp.exec($('title').text());
|
||||
if (!swf || !data) return done(new Error('Invalid page.'));
|
||||
done(null, {
|
||||
@@ -151,12 +153,13 @@ function scrapePlayer(config: typings.IConfig, address: string, id: number, done
|
||||
}, (err: Error, player: typings.IEpisodePlayerConfig) => {
|
||||
if (err) return done(err);
|
||||
try {
|
||||
var isSubtitled = Boolean(player['default:preload'].subtitle);
|
||||
done(null, {
|
||||
subtitle: {
|
||||
subtitle: isSubtitled ? {
|
||||
id: parseInt(player['default:preload'].subtitle.$.id, 10),
|
||||
iv: player['default:preload'].subtitle.iv,
|
||||
data: player['default:preload'].subtitle.data
|
||||
},
|
||||
} : null,
|
||||
video: {
|
||||
file: player['default:preload'].stream_info.file,
|
||||
host: player['default:preload'].stream_info.host
|
||||
@@ -167,4 +170,4 @@ function scrapePlayer(config: typings.IConfig, address: string, id: number, done
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
'use strict';
|
||||
export import batch = require('./batch');
|
||||
export import episode = require('./episode');
|
||||
export import series = require('./series');
|
||||
export import series = require('./series');
|
||||
|
||||
@@ -60,4 +60,4 @@ function modify(options: string|request.Options): request.Options {
|
||||
return options;
|
||||
}
|
||||
return {jar: true, url: options.toString()};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,4 +94,4 @@ function page(config: typings.IConfig, address: string, done: (err: Error, resul
|
||||
});
|
||||
done(null, {episodes: episodes.reverse(), series: title});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,4 +73,4 @@ function secret(size: number, modulo: number, firstSeed: number, secondSeed: num
|
||||
previousValue = oldValue;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ function event(block: typings.ISubtitleEvent): string {
|
||||
var format = 'Layer,Start,End,Style,Name,MarginL,MarginR,MarginV,Effect,Text';
|
||||
return '[Events]\n' +
|
||||
'Format: ' + format + '\n' +
|
||||
block.event.map(style => ('Dialogue: 0,' +
|
||||
[].concat(block.event).map(style => ('Dialogue: 0,' +
|
||||
style.$.start + ',' +
|
||||
style.$.end + ',' +
|
||||
style.$.style + ',' +
|
||||
@@ -66,7 +66,7 @@ function style(block: typings.ISubtitleStyle): string {
|
||||
'MarginL,MarginR,MarginV,Encoding';
|
||||
return '[V4+ Styles]\n' +
|
||||
'Format: ' + format + '\n' +
|
||||
block.style.map(style => 'Style: ' +
|
||||
[].concat(block.style).map(style => 'Style: ' +
|
||||
style.$.name + ',' +
|
||||
style.$.font_name + ',' +
|
||||
style.$.font_size + ',' +
|
||||
@@ -90,4 +90,4 @@ function style(block: typings.ISubtitleStyle): string {
|
||||
style.$.margin_r + ',' +
|
||||
style.$.margin_v + ',' +
|
||||
style.$.encoding).join('\n') + '\n';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,4 +7,4 @@ import typings = require('../../typings');
|
||||
var main: typings.IFormatterTable = {
|
||||
ass: ass,
|
||||
srt: srt
|
||||
};
|
||||
};
|
||||
|
||||
@@ -63,4 +63,4 @@ function time(value: string): string {
|
||||
var seconds = prefix(all[3], 2);
|
||||
var milliseconds = suffix(all[4], 3);
|
||||
return hours + ':' + minutes + ':' + seconds + ',' + milliseconds;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
'use strict';
|
||||
export import decode = require('./decode');
|
||||
export import formats = require('./formats/index');
|
||||
export import formats = require('./formats/index');
|
||||
|
||||
@@ -33,7 +33,7 @@ export interface IEpisodePage {
|
||||
}
|
||||
|
||||
export interface IEpisodePlayer {
|
||||
subtitle: {
|
||||
subtitle?: {
|
||||
id: number;
|
||||
iv: string;
|
||||
data: string;
|
||||
@@ -133,4 +133,4 @@ export interface ISubtitleStyle {
|
||||
encoding: string;
|
||||
};
|
||||
}[];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
'use strict';
|
||||
export import merge = require('./merge');
|
||||
export import stream = require('./stream');
|
||||
export import stream = require('./stream');
|
||||
|
||||
@@ -10,13 +10,13 @@ import typings = require('../typings');
|
||||
/**
|
||||
* Merges the subtitle and video files into a Matroska Multimedia Container.
|
||||
*/
|
||||
function main(config: typings.IConfig, rtmpInputPath: string, filePath: string, done: (err: Error) => void) {
|
||||
function main(config: typings.IConfig, isSubtitled: boolean, rtmpInputPath: string, filePath: string, done: (err: Error) => void) {
|
||||
var subtitlePath = filePath + '.' + (subtitle.formats[config.format] ? config.format : 'ass');
|
||||
var videoPath = filePath + path.extname(rtmpInputPath);
|
||||
childProcess.exec(command() + ' ' +
|
||||
'-o "' + filePath + '.mkv" ' +
|
||||
'"' + videoPath + '" ' +
|
||||
'"' + subtitlePath + '"', {
|
||||
(isSubtitled ? '"' + subtitlePath + '"' : ''), {
|
||||
maxBuffer: Infinity
|
||||
}, err => {
|
||||
if (err) return done(err);
|
||||
@@ -32,7 +32,7 @@ function main(config: typings.IConfig, rtmpInputPath: string, filePath: string,
|
||||
*/
|
||||
function command(): string {
|
||||
if (os.platform() !== 'win32') return 'mkvmerge';
|
||||
return path.join(__dirname, '../../bin/mkvmerge.exe');
|
||||
return '"' + path.join(__dirname, '../../bin/mkvmerge.exe') + '"';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,4 +55,4 @@ function unlinkTimeout(videoPath: string, subtitlePath: string, timeout: number)
|
||||
if (err) unlinkTimeout(videoPath, subtitlePath, timeout);
|
||||
});
|
||||
}, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,5 +22,5 @@ function main(rtmpUrl: string, rtmpInputPath: string, swfUrl: string, filePath:
|
||||
*/
|
||||
function command(): string {
|
||||
if (os.platform() !== 'win32') return 'rtmpdump';
|
||||
return path.join(__dirname, '../../bin/rtmpdump.exe');
|
||||
}
|
||||
return '"' + path.join(__dirname, '../../bin/rtmpdump.exe') + '"';
|
||||
}
|
||||
|
||||
23
ts.js
23
ts.js
@@ -4,6 +4,10 @@ var fs = require('fs');
|
||||
var path = require('path');
|
||||
var isTest = process.argv[2] === '--only-test';
|
||||
|
||||
// TODO: This file can use some cleaning up. We want to use the tsconfig.json
|
||||
// and go from there, but then without source maps. That should give us a final
|
||||
// build output. For now, this legacy build file will remain to do its job.
|
||||
|
||||
read(function(err, fileNames) {
|
||||
clean(fileNames, function() {
|
||||
var hasLintError = false;
|
||||
@@ -48,13 +52,13 @@ function clean(filePaths, done) {
|
||||
* @param {function(Error)} done
|
||||
*/
|
||||
function compile(filePaths, done) {
|
||||
if (isTest) return done(null);
|
||||
if (isTest) return done(null);
|
||||
var execPath = path.join(__dirname, 'node_modules/.bin/tsc');
|
||||
var options = '--declaration --module CommonJS --noImplicitAny --outDir dist';
|
||||
var options = '--declaration --module CommonJS --noImplicitAny --outDir dist --target ES5';
|
||||
childProcess.exec([execPath, options].concat(filePaths).join(' '), function(err, stdout) {
|
||||
if (stdout) return done(new Error(stdout));
|
||||
done(null);
|
||||
});
|
||||
if (stdout) return done(new Error(stdout));
|
||||
done(null);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,10 +87,5 @@ function lint(filePaths, handler, done) {
|
||||
* @param {function(Error, Array.<string>)} done
|
||||
*/
|
||||
function read(done) {
|
||||
var contents = fs.readFileSync('crunchyroll.js.njsproj', 'utf8');
|
||||
var expression = /<TypeScriptCompile\s+Include="([\w\W]+?\.ts)" \/>/g;
|
||||
var matches;
|
||||
var filePaths = [];
|
||||
while ((matches = expression.exec(contents))) filePaths.push(matches[1]);
|
||||
done(null, filePaths);
|
||||
}
|
||||
done(null, JSON.parse(fs.readFileSync('tsconfig.json', 'utf8')).files);
|
||||
}
|
||||
|
||||
41
tsconfig.json
Normal file
41
tsconfig.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"version": "1.4.1",
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"noImplicitAny": true,
|
||||
"removeComments": false,
|
||||
"module": "commonjs",
|
||||
"outDir": "dist",
|
||||
"sourceMap": true,
|
||||
"target": "es5"
|
||||
},
|
||||
"filesGlob": [
|
||||
"src/**/*.ts",
|
||||
"typings/**/*.ts"
|
||||
],
|
||||
"files": [
|
||||
"src/batch.ts",
|
||||
"src/cli.ts",
|
||||
"src/episode.ts",
|
||||
"src/index.ts",
|
||||
"src/request.ts",
|
||||
"src/series.ts",
|
||||
"src/subtitle/decode.ts",
|
||||
"src/subtitle/formats/ass.ts",
|
||||
"src/subtitle/formats/index.ts",
|
||||
"src/subtitle/formats/srt.ts",
|
||||
"src/subtitle/index.ts",
|
||||
"src/typings.ts",
|
||||
"src/video/index.ts",
|
||||
"src/video/merge.ts",
|
||||
"src/video/stream.ts",
|
||||
"typings/big-integer/big-integer.d.ts",
|
||||
"typings/cheerio/cheerio.d.ts",
|
||||
"typings/commander/commander.d.ts",
|
||||
"typings/form-data/form-data.d.ts",
|
||||
"typings/mkdirp/mkdirp.d.ts",
|
||||
"typings/node/node.d.ts",
|
||||
"typings/request/request.d.ts",
|
||||
"typings/xml2js/xml2js.d.ts"
|
||||
]
|
||||
}
|
||||
16
tsd.json
16
tsd.json
@@ -6,28 +6,28 @@
|
||||
"bundle": "typings/tsd.d.ts",
|
||||
"installed": {
|
||||
"node/node.d.ts": {
|
||||
"commit": "42c8a3b74c05f6887ce21dd63c6234e424f9f8fe"
|
||||
"commit": "3882d337bb0808cde9fe4c08012508a48c135482"
|
||||
},
|
||||
"commander/commander.d.ts": {
|
||||
"commit": "42c8a3b74c05f6887ce21dd63c6234e424f9f8fe"
|
||||
"commit": "3882d337bb0808cde9fe4c08012508a48c135482"
|
||||
},
|
||||
"xml2js/xml2js.d.ts": {
|
||||
"commit": "42c8a3b74c05f6887ce21dd63c6234e424f9f8fe"
|
||||
"commit": "3882d337bb0808cde9fe4c08012508a48c135482"
|
||||
},
|
||||
"cheerio/cheerio.d.ts": {
|
||||
"commit": "42c8a3b74c05f6887ce21dd63c6234e424f9f8fe"
|
||||
"commit": "3882d337bb0808cde9fe4c08012508a48c135482"
|
||||
},
|
||||
"mkdirp/mkdirp.d.ts": {
|
||||
"commit": "42c8a3b74c05f6887ce21dd63c6234e424f9f8fe"
|
||||
"commit": "3882d337bb0808cde9fe4c08012508a48c135482"
|
||||
},
|
||||
"request/request.d.ts": {
|
||||
"commit": "42c8a3b74c05f6887ce21dd63c6234e424f9f8fe"
|
||||
"commit": "3882d337bb0808cde9fe4c08012508a48c135482"
|
||||
},
|
||||
"big-integer/big-integer.d.ts": {
|
||||
"commit": "42c8a3b74c05f6887ce21dd63c6234e424f9f8fe"
|
||||
"commit": "3882d337bb0808cde9fe4c08012508a48c135482"
|
||||
},
|
||||
"form-data/form-data.d.ts": {
|
||||
"commit": "42c8a3b74c05f6887ce21dd63c6234e424f9f8fe"
|
||||
"commit": "3882d337bb0808cde9fe4c08012508a48c135482"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user