/trunk/LICENSE |
---|
0,0 → 1,202 |
Apache License |
Version 2.0, January 2004 |
http://www.apache.org/licenses/ |
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
1. Definitions. |
"License" shall mean the terms and conditions for use, reproduction, |
and distribution as defined by Sections 1 through 9 of this document. |
"Licensor" shall mean the copyright owner or entity authorized by |
the copyright owner that is granting the License. |
"Legal Entity" shall mean the union of the acting entity and all |
other entities that control, are controlled by, or are under common |
control with that entity. For the purposes of this definition, |
"control" means (i) the power, direct or indirect, to cause the |
direction or management of such entity, whether by contract or |
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
outstanding shares, or (iii) beneficial ownership of such entity. |
"You" (or "Your") shall mean an individual or Legal Entity |
exercising permissions granted by this License. |
"Source" form shall mean the preferred form for making modifications, |
including but not limited to software source code, documentation |
source, and configuration files. |
"Object" form shall mean any form resulting from mechanical |
transformation or translation of a Source form, including but |
not limited to compiled object code, generated documentation, |
and conversions to other media types. |
"Work" shall mean the work of authorship, whether in Source or |
Object form, made available under the License, as indicated by a |
copyright notice that is included in or attached to the work |
(an example is provided in the Appendix below). |
"Derivative Works" shall mean any work, whether in Source or Object |
form, that is based on (or derived from) the Work and for which the |
editorial revisions, annotations, elaborations, or other modifications |
represent, as a whole, an original work of authorship. For the purposes |
of this License, Derivative Works shall not include works that remain |
separable from, or merely link (or bind by name) to the interfaces of, |
the Work and Derivative Works thereof. |
"Contribution" shall mean any work of authorship, including |
the original version of the Work and any modifications or additions |
to that Work or Derivative Works thereof, that is intentionally |
submitted to Licensor for inclusion in the Work by the copyright owner |
or by an individual or Legal Entity authorized to submit on behalf of |
the copyright owner. For the purposes of this definition, "submitted" |
means any form of electronic, verbal, or written communication sent |
to the Licensor or its representatives, including but not limited to |
communication on electronic mailing lists, source code control systems, |
and issue tracking systems that are managed by, or on behalf of, the |
Licensor for the purpose of discussing and improving the Work, but |
excluding communication that is conspicuously marked or otherwise |
designated in writing by the copyright owner as "Not a Contribution." |
"Contributor" shall mean Licensor and any individual or Legal Entity |
on behalf of whom a Contribution has been received by Licensor and |
subsequently incorporated within the Work. |
2. Grant of Copyright License. Subject to the terms and conditions of |
this License, each Contributor hereby grants to You a perpetual, |
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
copyright license to reproduce, prepare Derivative Works of, |
publicly display, publicly perform, sublicense, and distribute the |
Work and such Derivative Works in Source or Object form. |
3. Grant of Patent License. Subject to the terms and conditions of |
this License, each Contributor hereby grants to You a perpetual, |
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
(except as stated in this section) patent license to make, have made, |
use, offer to sell, sell, import, and otherwise transfer the Work, |
where such license applies only to those patent claims licensable |
by such Contributor that are necessarily infringed by their |
Contribution(s) alone or by combination of their Contribution(s) |
with the Work to which such Contribution(s) was submitted. If You |
institute patent litigation against any entity (including a |
cross-claim or counterclaim in a lawsuit) alleging that the Work |
or a Contribution incorporated within the Work constitutes direct |
or contributory patent infringement, then any patent licenses |
granted to You under this License for that Work shall terminate |
as of the date such litigation is filed. |
4. Redistribution. You may reproduce and distribute copies of the |
Work or Derivative Works thereof in any medium, with or without |
modifications, and in Source or Object form, provided that You |
meet the following conditions: |
(a) You must give any other recipients of the Work or |
Derivative Works a copy of this License; and |
(b) You must cause any modified files to carry prominent notices |
stating that You changed the files; and |
(c) You must retain, in the Source form of any Derivative Works |
that You distribute, all copyright, patent, trademark, and |
attribution notices from the Source form of the Work, |
excluding those notices that do not pertain to any part of |
the Derivative Works; and |
(d) If the Work includes a "NOTICE" text file as part of its |
distribution, then any Derivative Works that You distribute must |
include a readable copy of the attribution notices contained |
within such NOTICE file, excluding those notices that do not |
pertain to any part of the Derivative Works, in at least one |
of the following places: within a NOTICE text file distributed |
as part of the Derivative Works; within the Source form or |
documentation, if provided along with the Derivative Works; or, |
within a display generated by the Derivative Works, if and |
wherever such third-party notices normally appear. The contents |
of the NOTICE file are for informational purposes only and |
do not modify the License. You may add Your own attribution |
notices within Derivative Works that You distribute, alongside |
or as an addendum to the NOTICE text from the Work, provided |
that such additional attribution notices cannot be construed |
as modifying the License. |
You may add Your own copyright statement to Your modifications and |
may provide additional or different license terms and conditions |
for use, reproduction, or distribution of Your modifications, or |
for any such Derivative Works as a whole, provided Your use, |
reproduction, and distribution of the Work otherwise complies with |
the conditions stated in this License. |
5. Submission of Contributions. Unless You explicitly state otherwise, |
any Contribution intentionally submitted for inclusion in the Work |
by You to the Licensor shall be under the terms and conditions of |
this License, without any additional terms or conditions. |
Notwithstanding the above, nothing herein shall supersede or modify |
the terms of any separate license agreement you may have executed |
with Licensor regarding such Contributions. |
6. Trademarks. This License does not grant permission to use the trade |
names, trademarks, service marks, or product names of the Licensor, |
except as required for reasonable and customary use in describing the |
origin of the Work and reproducing the content of the NOTICE file. |
7. Disclaimer of Warranty. Unless required by applicable law or |
agreed to in writing, Licensor provides the Work (and each |
Contributor provides its Contributions) on an "AS IS" BASIS, |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
implied, including, without limitation, any warranties or conditions |
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
PARTICULAR PURPOSE. You are solely responsible for determining the |
appropriateness of using or redistributing the Work and assume any |
risks associated with Your exercise of permissions under this License. |
8. Limitation of Liability. In no event and under no legal theory, |
whether in tort (including negligence), contract, or otherwise, |
unless required by applicable law (such as deliberate and grossly |
negligent acts) or agreed to in writing, shall any Contributor be |
liable to You for damages, including any direct, indirect, special, |
incidental, or consequential damages of any character arising as a |
result of this License or out of the use or inability to use the |
Work (including but not limited to damages for loss of goodwill, |
work stoppage, computer failure or malfunction, or any and all |
other commercial damages or losses), even if such Contributor |
has been advised of the possibility of such damages. |
9. Accepting Warranty or Additional Liability. While redistributing |
the Work or Derivative Works thereof, You may choose to offer, |
and charge a fee for, acceptance of support, warranty, indemnity, |
or other liability obligations and/or rights consistent with this |
License. However, in accepting such obligations, You may act only |
on Your own behalf and on Your sole responsibility, not on behalf |
of any other Contributor, and only if You agree to indemnify, |
defend, and hold each Contributor harmless for any liability |
incurred by, or claims asserted against, such Contributor by reason |
of your accepting any such warranty or additional liability. |
END OF TERMS AND CONDITIONS |
APPENDIX: How to apply the Apache License to your work. |
To apply the Apache License to your work, attach the following |
boilerplate notice, with the fields enclosed by brackets "[]" |
replaced with your own identifying information. (Don't include |
the brackets!) The text should be enclosed in the appropriate |
comment syntax for the file format. We also recommend that a |
file or class name and description of purpose be included on the |
same "printed page" as the copyright notice for easier |
identification within third-party archives. |
Copyright 2018 Daniel Marschall, ViaThinkSoft |
Licensed under the Apache License, Version 2.0 (the "License"); |
you may not use this file except in compliance with the License. |
You may obtain a copy of the License at |
http://www.apache.org/licenses/LICENSE-2.0 |
Unless required by applicable law or agreed to in writing, software |
distributed under the License is distributed on an "AS IS" BASIS, |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
See the License for the specific language governing permissions and |
limitations under the License. |
/trunk/README |
---|
0,0 → 1,96 |
ViaThinkSoft YouTube Downloader Util 2.2 |
Author: Daniel Marschall <www.daniel-marschall.de> |
Licensed under the terms of the Apache 2.0 license |
Syntax: |
./ytdwn [-t|--type v:[ext]|a:[ext]] (default v:) |
[-o|--outputDir <dir>] (default current working directory) |
[-a|--alreadyDownloaded <file>] |
[-f|--failList <file> <treshold>] (This file logs failures) |
[-F|--failTreshold <num>] (Don't download if failure (-f) treshold is reached. Default: 3) |
[-V|--version] (shows version) |
[-v|--verbose] (displays verbose information to STDOUT) |
[-h|--help] (shows help) |
[-N|--no-mp3-tagtransfer] (disables transfer of video ID to MP3 ID tag) |
(This feature requires the package "id3v2") |
[-T|--default-template <t>] (Sets default filename template.) |
(Default: '%(title)s-%(id)s.%(ext)s') |
[-X|--extra-args <args>] (Additional arguments passed through) |
(youtube-dl. Default "-ic") |
[-A|--api-key <file|key>] (specifies the API key, or a file containing the API key) |
(Default: ~/.yt_api_key) |
[--cookies=<file>] A netscape compatible cookie file (for age restricted videos) |
(Default: ~/.yt_cookkies) |
[-C|--resultcache <file>] (allows video results to be cached in this file) |
(only for playlists or channels) |
[-O|--create-outputdir] (allows creation of the output directories, recursively) |
[--] |
<resource> [<resource> ...] |
For all paths (outputDir, alreadyDownloaded, apikey, failList and resultcache), you can use the |
term '[listname]' which will be replaced by the basename of the current list file (without file extension). |
For example you can do following: |
./ytdwn -o 'downloads/[listname]' -- list:*.list |
If no list file is processed, it will be replaced with nothing. |
The "alreadyDownloaded" argument contains a file which will be managed by ytdwn. |
It will contain all video IDs which have been downloaded. This allows you to |
move away the already downloaded files, and ytdwn will not download them again. |
Examples for type: |
v: best video quality |
a: best audio only |
a:mp3 audio only, mp3 |
Valid audio formats according to "man youtube-dl": |
"best", "aac", "flac", "mp3", "m4a", "opus", "vorbis", or "wav"; "best" by default |
A <resource> can be one of the following: |
vid:<video ID> |
vurl:<youtube video URL> |
pid:<playlist ID> |
purl:<playlist URL> |
cid:<channel id> |
cname:<channel name> |
curl:<channel or username URL> |
list:<file with resource entries> (comments can be #) |
search:<searchterm> |
For channels (cid, cname, curl) you can also perform a search to filter the results. |
This can be done like this: |
cname:[search="Elvis Presley"]channel_1234 |
For the search option, following parameters are possible: |
search:[order=date][maxresults=50]"Elvis Presley" |
Acceptable order values are: date, rating, relevance, title, videoCount, viewCount |
Default values are order=relevance and maxresults=10 |
Use maxresults=-1 to download everything which matches the searchterm. |
Requirements: |
- PHP CLI |
- Package "youtube-dl" (ytdwn will try to download it automatically, if possible) |
- A YouTube API key (can be obtained here: https://console.developers.google.com/apis/credentials ) |
- If you want to extract audio, you need additionally: ffmpeg or avconv and ffprobe or avprobe. |
- Optional: package "id3v2" to allow the YouTube video id to be transferred to the MP3 ID tag |
Age restricted videos how-to |
---------------------------- |
To download age restricted videos, you need to supply cookies from a browser that has been logged in to YouTube. |
Here is a method how to do this: |
(1) Download and install this Chrome extension: |
https://chrome.google.com/webstore/detail/cookiestxt/njabckikapfpffapmjgojcnbfjonfjfg/related |
(2) If you cannot see the Cookie-Button at the right top, then click the plugin button, and then enable "pinning" for the plugin "cookie.txt". |
(3) Login to YouTube at the same network where the YouTube Downloader will run. |
Press the cookie plugin button and copy the contents to a file called cookies.txt |
(4) Edit cookies.txt and add following comment at the very top: |
# HTTP Cookie File |
(5) Rename and move the file to ~/.yt_cookies |
OR |
Add the argument "--cookies=cookies.txt" to ytdwn. |
/trunk/ytdwn |
---|
1,77 → 1,12 |
#!/usr/bin/php |
<?php |
// ViaThinkSoft YouTube Downloader Util 2.1.1 |
// Revision: 2019-08-05 |
// ViaThinkSoft YouTube Downloader Util 2.2 |
// Revision: 2020-07-25 |
// Author: Daniel Marschall <www.daniel-marschall.de> |
// Licensed under the terms of the Apache 2.0 license |
// |
// Syntax: |
// ./ytdwn [-t|--type v:[ext]|a:[ext]] (default v:) |
// [-o|--outputDir <dir>] (default current working directory) |
// [-a|--alreadyDownloaded <file>] |
// [-f|--failList <file> <treshold>] (This file logs failures) |
// [-F|--failTreshold <num>] (Don't download if failure (-f) treshold is reached. Default: 3) |
// [-V|--version] (shows version) |
// [-v|--verbose] (displays verbose information to STDOUT) |
// [-h|--help] (shows help) |
// [-N|--no-mp3-tagtransfer] (disables transfer of video ID to MP3 ID tag) |
// (This feature requires the package "id3v2") |
// [-T|--default-template <t>] (Sets default filename template.) |
// (Default: '%(title)s-%(id)s.%(ext)s') |
// [-X|--extra-args <args>] (Additional arguments passed through) |
// (youtube-dl. Default "-ic") |
// [-A|--api-key <file|key>] (specifies the API key, or a file containing the API key) |
// (Default: ~/.yt_api_key) |
// [-C|--resultcache <file>] (allows video results to be cached in this file) |
// (only for playlists or channels) |
// [-O|--create-outputdir] (allows creation of the output directories, recursively) |
// [--] |
// <resource> [<resource> ...] |
// |
// For all paths (outputDir, alreadyDownloaded, apikey, failList and resultcache), you can use the |
// term '[listname]' which will be replaced by the basename of the current list file (without file extension). |
// For example you can do following: |
// ./ytdwn -o 'downloads/[listname]' -- list:*.list |
// If no list file is processed, it will be replaced with nothing. |
// |
// The "alreadyDownloaded" argument contains a file which will be managed by ytdwn. |
// It will contain all video IDs which have been downloaded. This allows you to |
// move away the already downloaded files, and ytdwn will not download them again. |
// |
// Examples for type: |
// v: best video quality |
// a: best audio only |
// a:mp3 audio only, mp3 |
// Valid audio formats according to "man youtube-dl": |
// "best", "aac", "flac", "mp3", "m4a", "opus", "vorbis", or "wav"; "best" by default |
// |
// A <resource> can be one of the following: |
// vid:<video ID> |
// vurl:<youtube video URL> |
// pid:<playlist ID> |
// purl:<playlist URL> |
// cid:<channel id> |
// cname:<channel name> |
// curl:<channel or username URL> |
// list:<file with resource entries> (comments can be #) |
// search:<searchterm> |
// |
// For channels (cid, cname, curl) you can also perform a search to filter the results. |
// This can be done like this: |
// cname:[search="Elvis Presley"]channel_1234 |
// For the search option, following parameters are possible: |
// search:[order=date][maxresults=50]"Elvis Presley" |
// Acceptable order values are: date, rating, relevance, title, videoCount, viewCount |
// Default values are order=relevance and maxresults=10 |
// Use maxresults=-1 to download everything which matches the searchterm. |
// |
// Requirements: |
// - PHP CLI |
// - Package "youtube-dl" (ytdwn will try to download it automatically, if possible) |
// - A YouTube API key (can be obtained here: https://console.developers.google.com/apis/credentials ) |
// - If you want to extract audio, you need additionally: ffmpeg or avconv and ffprobe or avprobe. |
// - Optional: package "id3v2" to allow the YouTube video id to be transferred to the MP3 ID tag |
// For syntax and other documentation, please read the file README. |
// ------------------------------------------------------------------------------------------------ |
78,6 → 13,7 |
error_reporting(E_ALL | E_NOTICE | E_STRICT | E_DEPRECATED); |
define('AUTO_API_KEY', '~/.yt_api_key'); |
define('AUTO_COOKIE_FILE', '~/.yt_cookies'); |
define('DOWNLOAD_SIMULATION_MODE', false); |
define('DEFAULT_SEARCH_ORDER', 'relevance'); |
define('DEFAULT_SEARCH_MAXRESULTS', 10); |
115,6 → 51,7 |
'-i ' . // continue upon download errors |
'-c '; // resume partially downloaded video files |
$default_template = '%(title)s-%(id)s.%(ext)s'; |
$cookie_file = AUTO_COOKIE_FILE; |
// Parse arguments |
// We do not use getopt() at the moment, because the important functionality "optind" is only available in PHP 7.1, which is not yet distributed with most of the stable Linux distros |
157,6 → 94,10 |
array_shift($argv_bak); |
if (count($rest_args) > 0) syntax_error("Invalid argument: ".$rest_args[0]); |
$apikey = file_exists($m[3]) ? trim(file_get_contents($m[3])) : $m[3]; |
} else if (preg_match('@^(\-\-cookies)(\s+|=)(.*)$@s', $arg2, $m)) { |
array_shift($argv_bak); |
if (count($rest_args) > 0) syntax_error("Invalid argument: ".$rest_args[0]); |
$cookie_file = file_exists($m[3]) ? trim(file_get_contents($m[3])) : $m[3]; |
} else if (preg_match('@^(/X|\-X|\-\-extra-args)(\s+|=)(.*)$@s', $arg2, $m)) { |
array_shift($argv_bak); |
if (count($rest_args) > 0) syntax_error("Invalid argument: ".$rest_args[0]); |
201,6 → 142,9 |
if ($failTreshold <= 0) syntax_error("Fail treshold has invalid value. Must be >0."); |
$cookie_file = expand_tilde($cookie_file); |
if (!file_exists($cookie_file)) $cookie_file = ''; |
// Try to download/update youtube-dl into local directory |
$newest_version_md5 = get_latest_ytdl_md5sum(); |
433,6 → 377,10 |
// Now download |
if (!$out[$key]['results']) { |
fwrite(STDERR, "Cannot get result for channel with ID '$channel_id'\n"); |
return; |
} |
foreach ($out[$key]['results'] as list($id, $title)) { |
if ($verbose) echo "Downloading '$title' as ".hf_type($type)." ...\n"; |
ytdwn_video_id($id); |
483,6 → 431,10 |
// Now download |
if (!$out[$key]['results']) { |
fwrite(STDERR, "Cannot get result for playlist with ID '$playlist_id'\n"); |
return; |
} |
foreach ($out[$key]['results'] as list($id, $title)) { |
if ($verbose) echo "Downloading '$title' as ".hf_type($type)." ...\n"; |
ytdwn_video_id($id); |
501,6 → 453,10 |
// Now download |
if (!$results) { |
fwrite(STDERR, "Cannot get data for search '$search'\n"); |
return; |
} |
foreach ($results as list($id, $title)) { |
if ($verbose) echo "Downloading '$title' as ".hf_type($type)." ...\n"; |
ytdwn_video_id($id); |
514,6 → 470,7 |
global $extra_args; |
global $default_template; |
global $failTreshold; |
global $cookie_file; |
if (DOWNLOAD_SIMULATION_MODE) { |
echo "SIMULATE download of video id $video_id as ".hf_type($type)." to "._getOutputDir()."\n"; |
538,16 → 495,16 |
if (substr($type,0,2) == 'v:') { |
$format = substr($type,2); |
if (!empty($format)) { |
exec(YTDL_EXE.' -o '.escapeshellarg($outputTemplate).' '.$extra_args.' '.escapeshellarg(vid_to_vurl($video_id)).' --format '.escapeshellarg($format), $out, $code); |
exec(YTDL_EXE.' -o '.escapeshellarg($outputTemplate).' '.$extra_args.(empty($cookie_file) ? '' : ' --cookies '.$cookie_file).' '.escapeshellarg(vid_to_vurl($video_id)).' --format '.escapeshellarg($format), $out, $code); |
} else { |
exec(YTDL_EXE.' -o '.escapeshellarg($outputTemplate).' '.$extra_args.' '.escapeshellarg(vid_to_vurl($video_id)), $out, $code); |
exec(YTDL_EXE.' -o '.escapeshellarg($outputTemplate).' '.$extra_args.(empty($cookie_file) ? '' : ' --cookies '.$cookie_file).' '.escapeshellarg(vid_to_vurl($video_id)), $out, $code); |
} |
} else if (substr($type,0,2) == 'a:') { |
$format = substr($type,2); |
if (!empty($format)) { |
exec(YTDL_EXE.' -o '.escapeshellarg($outputTemplate).' '.$extra_args.' '.escapeshellarg(vid_to_vurl($video_id)).' --extract-audio --audio-format '.escapeshellarg($format), $out, $code); |
exec(YTDL_EXE.' -o '.escapeshellarg($outputTemplate).' '.$extra_args.(empty($cookie_file) ? '' : ' --cookies '.$cookie_file).' '.escapeshellarg(vid_to_vurl($video_id)).' --extract-audio --audio-format '.escapeshellarg($format), $out, $code); |
} else { |
exec(YTDL_EXE.' -o '.escapeshellarg($outputTemplate).' '.$extra_args.' '.escapeshellarg(vid_to_vurl($video_id)).' --extract-audio', $out, $code); |
exec(YTDL_EXE.' -o '.escapeshellarg($outputTemplate).' '.$extra_args.(empty($cookie_file) ? '' : ' --cookies '.$cookie_file).' '.escapeshellarg(vid_to_vurl($video_id)).' --extract-audio', $out, $code); |
} |
if (($mp3id_transfer) && ($format == 'mp3')) mp3_transfer_vid_to_id(); |
} else assert(false); |