12 Commits
0.01 ... 0.03

4 changed files with 106 additions and 21 deletions

View File

@@ -2,11 +2,13 @@
A web service and bookmarklet to download videos with a single click.
![Screencast](/screencast.gif)
## Pre-requisites
* a passing familiarity with the command line
* youtube-dl (plus any of its required dependencies, like ffmpeg)
* golang compiler
* golang compiler (if you'd like to build from source)
## Build
@@ -23,29 +25,58 @@ Binaries are available at https://github.com/tardisx/gropple/releases
With no arguments, it will listen on port 6283 and use an address of 'http://localhost:6283'.
The address must be specified so that the bookmarklet can refer to the correct
host when it is not running on your local machine. You may also need to specify
host if it is not running on your local machine. You may also need to specify
a different address if you are running it behind a proxy server or similar.
## Using
Bring up `http://localhost:6283` (or your chosen address) in your browser. You should see a link to the bookmarklet at the top of the screen, and the list of downloads (currently empty).
Bring up `http://localhost:6283` (or your chosen address) in your browser. You
should see a link to the bookmarklet at the top of the screen, and the list of
downloads (currently empty).
Drag the bookmarklet to your favourites bar, or otherwise bookmark it as you see fit.
Drag the bookmarklet to your favourites bar, or otherwise bookmark it as you
see fit.
Whenever you are on a page with a video you would like to download, simply click the bookmarklet.
Whenever you are on a page with a video you would like to download, simply
click the bookmarklet.
A popup window will appear, the download will start on the your gropple server and the status will be shown in the window.
A popup window will appear, the download will start on the your gropple server
and the status will be shown in the window.
You may close this window at any time without stopping the download, the status of all downloads is available on the index page.
You may close this window at any time without stopping the download, the status
of all downloads is available on the index page.
## Using an alternative downloader
The default downloader is youtube-dl. It is possible to use a different downloader
via the `-dl-cmd` command line option.
While `gropple` will use your `PATH` to find the executable, you may also want
to specify a full path instead.o
So, for instance, to use `youtube-dlc` instead of `youtube-dl` and specify the
full path:
`gropple -dl-cmd /home/username/bin/youtube-dlc`
Note that this is only the path to the executable. If you need to change the
command arguments, see below.
## Changing the youtube-dl arguments
The default arguments passed to `youtube-dl` are:
* `--newline` (needed to allow gropple to properly parse the output)
* `--write-info-json` (optional, but provides information on the download in the corresponding .json file)
* `-f` and `bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best` (choose the type of video `youtube-dl` will download)
These are customisable on the command line for `gropple`. For example, to duplicate these default options, you would
do:
`gropple -dl-args '--newline' -dl-args '--write-info-json' -dl-args '-f' -dl-args 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best`
## TODO
Many things. Please raise an issue after checking the [currently open issues](https://github.com/tardisx/gropple/issues).
* queue downloads if too many started (maybe by domain)
* show logs from the index page
* process logs better to note post-processing (for instance when video and audio are downloaded separately and then combined)
* configurable options for youtube-dl, or the ability to use various youtube-dl forks

64
main.go
View File

@@ -39,18 +39,45 @@ var downloadPath = "./"
var address string
const currentVersion = "v0.01"
var dlCmd = "youtube-dl"
type args []string
var dlArgs = args{}
var defaultArgs = args{
"--write-info-json",
"-f", "bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best",
"--newline",
}
const currentVersion = "v0.03"
//go:embed web
var webFS embed.FS
func (i *args) Set(value string) error {
*i = append(*i, strings.TrimSpace(value))
return nil
}
func (i *args) String() string {
return strings.Join(*i, ",")
}
func main() {
var port int
flag.IntVar(&port, "port", 6283, "port to listen on")
flag.StringVar(&address, "address", "http://localhost:6283", "address for the service")
flag.StringVar(&downloadPath, "path", "", "path for downloaded files - defaults to current directory")
flag.StringVar(&dlCmd, "dl-cmd", "youtube-dl", "downloader to use")
flag.Var(&dlArgs, "dl-args", "arguments to the downloader")
flag.Parse()
if len(dlArgs) == 0 {
dlArgs = defaultArgs
}
r := mux.NewRouter()
r.HandleFunc("/", HomeHandler)
r.HandleFunc("/fetch", FetchHandler)
@@ -164,13 +191,11 @@ func FetchHandler(w http.ResponseWriter, r *http.Request) {
}
func queue(dl *download) {
cmdSlice := []string{}
cmdSlice = append(cmdSlice, dlArgs...)
cmdSlice = append(cmdSlice, dl.Url)
cmd := exec.Command(
"youtube-dl",
"--write-info-json",
"-f", "bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best",
"--newline", dl.Url,
)
cmd := exec.Command(dlCmd, cmdSlice...)
cmd.Dir = downloadPath
stdout, err := cmd.StdoutPipe()
@@ -281,4 +306,29 @@ func updateMetadata(dl *download, s string) {
if len(matches) == 2 {
dl.Files = append(dl.Files, matches[1])
}
// This means a file has been "created" by merging others
// [ffmpeg] Merging formats into "Toto - Africa (Official HD Video)-FTQbiNvZqaY.mp4"
mergedFilename := regexp.MustCompile(`Merging formats into "(.+)$`)
matches = mergedFilename.FindStringSubmatch(s)
if len(matches) == 2 {
dl.Files = append(dl.Files, matches[1])
}
// This means a file has been deleted
// Gross - this time it's unquoted and has trailing guff
// Deleting original file Toto - Africa (Official HD Video)-FTQbiNvZqaY.f137.mp4 (pass -k to keep)
// This is very fragile
deletedFile := regexp.MustCompile(`Deleting original file (.+) \(pass -k to keep\)$`)
matches = deletedFile.FindStringSubmatch(s)
if len(matches) == 2 {
// find the index
for i, f := range dl.Files {
if f == matches[1] {
dl.Files = append(dl.Files[:i], dl.Files[i+1:]...)
break
}
}
}
}

BIN
screencast.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 MiB

View File

@@ -8,7 +8,11 @@
<link rel="stylesheet" href="https://unpkg.com/purecss@2.0.6/build/pure-min.css" integrity="sha384-Uu6IeWbM+gzNVXJcM9XV3SohHtmWE+3VGi496jvgX1jyvDTXfdK+rfZc8C1Aehk5" crossorigin="anonymous">
<link rel="stylesheet" href="https://unpkg.com/purecss@2.0.6/build/grids-responsive-min.css">
<style>
pre { font-size: 70%; }
pre {
font-size: 60%;
height: 100px;
overflow:auto;
}
</style>
</head>
<body style="margin:4; padding:4">