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

refactor and embed thumbnail #2

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
# Go-Youtube-dl
A GoLang library for downloading youtube subtitles and meta data using the known [Youtube-dl](https://rg3.github.io/youtube-dl/) application.
A GoLang library and cli for downloading audio, video and subtitles with meta data using the known [Youtube-dl](https://rg3.github.io/youtube-dl/) application.

![Go-youtube-dl logo](https://golang.org/doc/gopher/appenginegopher.jpg "Golang Gopher")

---------------------------------------
* [Features](#features)
* [Requirements](#requirements)
* [Installation](#installation)
* [Usage](#usage)
* [API Usage](#api-usage)
* [CLI Usage](#cli-usage)
* [License](#license)

---------------------------------------
Expand All @@ -29,7 +30,7 @@ $ go get github.com/youtube-videos/go-youtube-dl
```
Make sure [Git is installed](https://git-scm.com/downloads) on your machine and in your system's `PATH`.

## Usage
## API Usage
Example of usage is as follow:
```bash
ytdl := youtube_dl.YoutubeDl{}
Expand All @@ -41,6 +42,21 @@ if err != nil {
```
Then you can handle the downloaded file in the specified path.

## CLI Usage
```
go-youtube-dl -h
Usage of ./go-youtube-dl:
-a download audio.
-f string
Specific media format to download.
-p string
Path where you want to download. (default "/home/${USER}/Music")
-s Download subs from the youtube for the specified video id
-v download video.
-y Find where youtube-dl is installed.
-yid string
ID of the youtube video to download subs
```
---------------------------------------

## License
Expand Down
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module github.com/sanfx/go-youtube-dl

go 1.18
241 changes: 241 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
package main


import (
"io"
"flag"
"fmt"
"net/url"
"os"
"log"
"os/exec"
"os/user"
"path/filepath"
)


const CMD = "youtube-dl"
const BEST_VIDEO_FORMAT = "18"
const BEST_AUDIO_FORMAT = "140"


// Youtube-dl Downloader
type YoutubeDl struct {
Path string
Format string
}

func extractVideoID(videoURL string) (string, error) {
parsedURL, err := url.Parse(videoURL)
if err != nil {
return "", err
}

queryParams := parsedURL.Query()
videoID := queryParams.Get("v")

return videoID, nil
}


func (youtubedl YoutubeDl) DownloadSubs(url string) error {
videoID, error := extractVideoID(url)
if error != nil {
fmt.Fprintln(os.Stderr, error)
return error
}

cmdArgs := []string{
CMD,
"--write-auto-sub",
"--sub-lang",
"en",
"--output", youtubedl.Path + videoID + ".srt",
"--skip-download",
url,
}

err := run(cmdArgs)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return err
}

return nil
}

func (youtubedl YoutubeDl) DownloadAudio(url string) (error) {

cmdArgs := []string{
CMD,
"--format", youtubedl.Format,
"--extract-audio",
"--audio-format", "m4a",
"--audio-quality", "192",
"--output", youtubedl.Path + "%(title)s-%(id)s.%(ext)s\"",
"--write-thumbnail",
"--embed-thumbnail",
url,
}

err := run(cmdArgs)
if err != nil {
fmt.Fprintln(os.Stderr, err)
return err
}
return nil
}

func (youtubedl YoutubeDl) DownloadVideo(videoURL string) error {
sep := string(filepath.Separator)
// Escape and quote the path to handle spaces or special characters
escapedPath := "\"" + youtubedl.Path + "%(title)s-%(id)s.%(ext)s\""

cmdArgs := []string{
CMD,
"--format", youtubedl.Format,
"--output", escapedPath,
"--embed-thumbnail",
videoURL,
}

return run(cmdArgs)
}

func run(cmdArgs []string) error {
fmt.Println("Starting ...")
cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)

stdout, err := cmd.StdoutPipe()
if err != nil {
log.Fatal(err)
}

stderr, err := cmd.StderrPipe()
if err != nil {
log.Fatal(err)
}

fmt.Println("Executing command: ", cmd.String())

if err := cmd.Start(); err != nil {
log.Fatal(err)
}

go func() {
defer stdout.Close()
io.Copy(os.Stdout, stdout)
}()

go func() {
defer stderr.Close()
io.Copy(os.Stderr, stderr)
}()

if err := cmd.Wait(); err != nil {
log.Fatal(err)
return err
}

return nil
}

func main() {

var (
audioFlag bool
format string
output string
subsFlag bool
url string
videoFlag bool
ytdlFlag bool
)

usr, err := user.Current()
if err != nil {
panic(err)
}
sep := string(filepath.Separator)
path := filepath.Join(sep, "home", usr.Username, "Music")

// Parsing command line flags
flag.StringVar(&url, "url", "", "url of the youtube /audio/video to download")
flag.BoolVar(&subsFlag, "s", false, "Download subs from the youtube for the specified video")
flag.BoolVar(&audioFlag, "a", false, "Download audio")
flag.BoolVar(&videoFlag, "v", false, "Download video")
flag.StringVar(&format, "f", "", "Specify video format")
flag.StringVar(&output, "o", path + sep, "Path where the video will be written to")
flag.BoolVar(&ytdlFlag, "y", false, "Find where youtube-dl is installed and its version")

flag.Parse()

if _, err := os.Stat(output); os.IsNotExist(err) {
fmt.Printf("Error: The specified path '%s' does not exist.\n", output)
os.Exit(1)
}

// If user did not provide youtube video url, show usage.
if url == "" && !ytdlFlag {
flag.Usage()
os.Exit(1)
}

ytdl := YoutubeDl{Path: output + sep}

switch {
case ytdlFlag:
cmdp := exec.Command("which", "youtube-dl")
output, err := cmdp.CombinedOutput()
if err != nil {
fmt.Printf("Error executing command: %v\n", err)
return
}

fmt.Printf("youtube-dl is located at:\n%s\n", output)

cmdv := exec.Command("youtube-dl", "--version")
version, error := cmdv.CombinedOutput()
if error != nil {
fmt.Printf("Error executing command: %v\n", error)
return
}
fmt.Printf("Version:\n%s\n", version)

case audioFlag:
if format != "" {
ytdl.Format = format
} else {
ytdl.Format = BEST_AUDIO_FORMAT
}
err := ytdl.DownloadAudio(url)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}

case videoFlag:
if format != "" {
ytdl.Format = format
} else {
ytdl.Format = BEST_VIDEO_FORMAT
}
err := ytdl.DownloadVideo(url)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}

case subsFlag:
fmt.Println("Downloading subs...")
err := ytdl.DownloadSubs(url)
if err != nil {
fmt.Println("Error downloading video.")
}

default:
// Invalid flag provided
fmt.Fprintln(os.Stderr, fmt.Sprintf("Invalid option"))
os.Exit(1)
}
}
19 changes: 0 additions & 19 deletions youtube_dl.go

This file was deleted.