mirror of
https://github.com/crunchy-labs/crunchy-cli.git
synced 2026-01-21 04:02:00 -06:00
Fixed #3
This commit is contained in:
parent
291aae18f3
commit
cc549c817f
4 changed files with 49 additions and 36 deletions
6
Makefile
6
Makefile
|
|
@ -1,16 +1,16 @@
|
||||||
VERSION=1.0
|
VERSION=1.0.1
|
||||||
BINARY_NAME=crunchy
|
BINARY_NAME=crunchy
|
||||||
VERSION_BINARY_NAME=$(BINARY_NAME)-v$(VERSION)
|
VERSION_BINARY_NAME=$(BINARY_NAME)-v$(VERSION)
|
||||||
|
|
||||||
build:
|
build:
|
||||||
cd cmd/crunchyroll-go && CGO_ENABLED=0 go build -o $(BINARY_NAME)
|
cd cmd/crunchyroll-go && go build -o $(BINARY_NAME)
|
||||||
mv cmd/crunchyroll-go/$(BINARY_NAME) .
|
mv cmd/crunchyroll-go/$(BINARY_NAME) .
|
||||||
|
|
||||||
test:
|
test:
|
||||||
go test -v .
|
go test -v .
|
||||||
|
|
||||||
release:
|
release:
|
||||||
cd cmd/crunchyroll-go && CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o $(VERSION_BINARY_NAME)_linux
|
cd cmd/crunchyroll-go && GOOS=linux GOARCH=amd64 go build -o $(VERSION_BINARY_NAME)_linux
|
||||||
cd cmd/crunchyroll-go && GOOS=windows GOARCH=amd64 go build -o $(VERSION_BINARY_NAME)_windows.exe
|
cd cmd/crunchyroll-go && GOOS=windows GOARCH=amd64 go build -o $(VERSION_BINARY_NAME)_windows.exe
|
||||||
cd cmd/crunchyroll-go && GOOS=darwin GOARCH=amd64 go build -o $(VERSION_BINARY_NAME)_darwin
|
cd cmd/crunchyroll-go && GOOS=darwin GOARCH=amd64 go build -o $(VERSION_BINARY_NAME)_darwin
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path"
|
"path"
|
||||||
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -398,12 +399,12 @@ func findFormat(formats []*crunchyroll.Format) (format *crunchyroll.Format) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func downloadFormat(format *crunchyroll.Format, dir, fname string, info information) (_ bool) {
|
func downloadFormat(format *crunchyroll.Format, dir, fname string, info information) bool {
|
||||||
filename := freeFileName(path.Join(dir, fname))
|
filename := freeFileName(filepath.Join(dir, fname))
|
||||||
ext := path.Ext(filename)
|
ext := path.Ext(filename)
|
||||||
out.Debugf("Download filename: %s\n", filename)
|
out.Debugf("Download filename: %s\n", filename)
|
||||||
if filename != path.Join(dir, fname) {
|
if filename != filepath.Join(dir, fname) {
|
||||||
out.Errf("The file %s already exist, renaming the download file to %s\n", path.Join(dir, fname), filename)
|
out.Errf("The file %s already exist, renaming the download file to %s\n", filepath.Join(dir, fname), filename)
|
||||||
}
|
}
|
||||||
if ext != ".ts" {
|
if ext != ".ts" {
|
||||||
if !hasFFmpeg() {
|
if !hasFFmpeg() {
|
||||||
|
|
@ -419,7 +420,7 @@ func downloadFormat(format *crunchyroll.Format, dir, fname string, info informat
|
||||||
out.Errf("Failed to get %s subtitles\n", info.Subtitle)
|
out.Errf("Failed to get %s subtitles\n", info.Subtitle)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
subtitleFilename = freeFileName(path.Join(dir, fmt.Sprintf("%s.%s", strings.TrimRight(path.Base(filename), ext), subtitle.Format)))
|
subtitleFilename = freeFileName(filepath.Join(dir, fmt.Sprintf("%s.%s", strings.TrimRight(path.Base(filename), ext), subtitle.Format)))
|
||||||
out.Debugf("Subtitles will be saved as `%s`\n", subtitleFilename)
|
out.Debugf("Subtitles will be saved as `%s`\n", subtitleFilename)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -436,7 +437,7 @@ func downloadFormat(format *crunchyroll.Format, dir, fname string, info informat
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
out.Errf("Could not create file `%s` to download episode `%s` (%s): %s, skipping\n", filename, info.Title, info.OriginalURL, err)
|
out.Errf("Could not create file `%s` to download episode `%s` (%s): %s, skipping\n", filename, info.Title, info.OriginalURL, err)
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
cleanup[0] = filename
|
cleanup[0] = filename
|
||||||
|
|
||||||
|
|
@ -454,13 +455,16 @@ func downloadFormat(format *crunchyroll.Format, dir, fname string, info informat
|
||||||
}()
|
}()
|
||||||
|
|
||||||
err = format.Download(file, downloadProgress)
|
err = format.Download(file, downloadProgress)
|
||||||
|
// newline to avoid weird output
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
// make the goroutine stop
|
// make the goroutine stop
|
||||||
sigs <- sigusr1
|
sigs <- sigusr1
|
||||||
} else {
|
} else {
|
||||||
tempDir, err := os.MkdirTemp("", "crunchy_")
|
tempDir, err := os.MkdirTemp("", "crunchy_")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
out.Errln("Failed to create temp download dir. Skipping")
|
out.Errln("Failed to create temp download dir. Skipping")
|
||||||
return
|
return false
|
||||||
}
|
}
|
||||||
sigs := make(chan os.Signal, 1)
|
sigs := make(chan os.Signal, 1)
|
||||||
signal.Notify(sigs, os.Interrupt, syscall.SIGTERM, sigusr1)
|
signal.Notify(sigs, os.Interrupt, syscall.SIGTERM, sigusr1)
|
||||||
|
|
@ -473,29 +477,29 @@ func downloadFormat(format *crunchyroll.Format, dir, fname string, info informat
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
var filenames []string
|
var segmentCount int
|
||||||
err = format.DownloadSegments(tempDir, 4, func(segment *m3u8.MediaSegment, current, total int, file *os.File, err error) error {
|
err = format.DownloadSegments(tempDir, 4, func(segment *m3u8.MediaSegment, current, total int, file *os.File, err error) error {
|
||||||
filenames = append(filenames, file.Name())
|
segmentCount++
|
||||||
return downloadProgress(segment, current, total, file, err)
|
return downloadProgress(segment, current, total, file, err)
|
||||||
})
|
})
|
||||||
|
// newline to avoid weird output
|
||||||
|
fmt.Println()
|
||||||
|
|
||||||
sort.Slice(filenames, func(i, j int) bool {
|
f, _ := os.CreateTemp("", "*.txt")
|
||||||
iNum, err := strconv.Atoi(strings.Split(path.Base(filenames[i]), ".")[0])
|
for i := 0; i < segmentCount; i++ {
|
||||||
if err != nil {
|
fmt.Fprintf(f, "file '%s.ts'\n", filepath.Join(tempDir, strconv.Itoa(i)))
|
||||||
return false
|
}
|
||||||
}
|
defer os.Remove(f.Name())
|
||||||
jNum, err := strconv.Atoi(strings.Split(path.Base(filenames[j]), ".")[0])
|
f.Close()
|
||||||
if err != nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return iNum < jNum
|
|
||||||
})
|
|
||||||
|
|
||||||
cmd := exec.Command("ffmpeg",
|
cmd := exec.Command("ffmpeg",
|
||||||
"-i", fmt.Sprintf("concat:%s", strings.Join(filenames, "|")),
|
"-f", "concat",
|
||||||
"-codec", "copy",
|
"-safe", "0",
|
||||||
|
"-i", f.Name(),
|
||||||
|
"-c", "copy",
|
||||||
filename)
|
filename)
|
||||||
err = cmd.Run()
|
err = cmd.Run()
|
||||||
|
|
||||||
sigs <- sigusr1
|
sigs <- sigusr1
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -513,7 +517,7 @@ func downloadFormat(format *crunchyroll.Format, dir, fname string, info informat
|
||||||
} else {
|
} else {
|
||||||
subtitle, ok := utils.SubtitleByLocale(format, info.Subtitle)
|
subtitle, ok := utils.SubtitleByLocale(format, info.Subtitle)
|
||||||
if !ok {
|
if !ok {
|
||||||
out.Errln("Failed to get %s subtitles\n", info.Subtitle)
|
out.Errf("Failed to get %s subtitles\n", info.Subtitle)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if err := subtitle.Download(file); err != nil {
|
if err := subtitle.Download(file); err != nil {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -19,7 +19,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
var sessionIDPath = path.Join(os.TempDir(), ".crunchy")
|
var sessionIDPath = filepath.Join(os.TempDir(), ".crunchy")
|
||||||
|
|
||||||
type progress struct {
|
type progress struct {
|
||||||
status bool
|
status bool
|
||||||
|
|
@ -89,11 +89,20 @@ func (l *logger) StartProgress(message string) {
|
||||||
l.progressWG.Lock()
|
l.progressWG.Lock()
|
||||||
select {
|
select {
|
||||||
case p := <-l.progress:
|
case p := <-l.progress:
|
||||||
fmt.Print("\r")
|
// clearing the last line
|
||||||
|
fmt.Printf("\r%s\r", strings.Repeat(" ", len(l.InfoLog.Prefix())+len(message)+2))
|
||||||
if p.status {
|
if p.status {
|
||||||
l.InfoLog.Printf("✅ %s", p.message)
|
successTag := "✔"
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
successTag = "~"
|
||||||
|
}
|
||||||
|
l.InfoLog.Printf("%s %s", successTag, p.message)
|
||||||
} else {
|
} else {
|
||||||
l.ErrLog.Printf("❌ %s", p.message)
|
errorTag := "✘"
|
||||||
|
if runtime.GOOS == "windows" {
|
||||||
|
errorTag = "!"
|
||||||
|
}
|
||||||
|
l.ErrLog.Printf("%s %s", errorTag, p.message)
|
||||||
}
|
}
|
||||||
l.progress = nil
|
l.progress = nil
|
||||||
l.progressWG.Unlock()
|
l.progressWG.Unlock()
|
||||||
|
|
|
||||||
10
format.go
10
format.go
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -108,7 +108,7 @@ func (f *Format) DownloadSegments(outputDir string, goroutines int, onSegmentDow
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
var file *os.File
|
var file *os.File
|
||||||
file, err = f.downloadSegment(segment, path.Join(outputDir, fmt.Sprintf("%d.ts", i+j)), block, iv)
|
file, err = f.downloadSegment(segment, filepath.Join(outputDir, fmt.Sprintf("%d.ts", i+j)), block, iv)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
quit <- true
|
quit <- true
|
||||||
break
|
break
|
||||||
|
|
@ -169,13 +169,13 @@ func (f *Format) downloadSegment(segment *m3u8.MediaSegment, filename string, bl
|
||||||
|
|
||||||
// some mpeg stream things. see the link beneath for more information
|
// some mpeg stream things. see the link beneath for more information
|
||||||
// https://github.com/oopsguy/m3u8/blob/4150e93ec8f4f8718875a02973f5d792648ecb97/dl/dowloader.go#L135
|
// https://github.com/oopsguy/m3u8/blob/4150e93ec8f4f8718875a02973f5d792648ecb97/dl/dowloader.go#L135
|
||||||
syncByte := uint8(71) //0x47
|
/*syncByte := uint8(71) //0x47
|
||||||
for k := 0; k < len(content); k++ {
|
for k := 0; k < len(content); k++ {
|
||||||
if content[k] == syncByte {
|
if content[k] == syncByte {
|
||||||
content = content[k:]
|
content = content[k:]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
file, err := os.Create(filename)
|
file, err := os.Create(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -212,7 +212,7 @@ func (f *Format) mergeSegments(tempPath string, output *os.File) error {
|
||||||
})
|
})
|
||||||
|
|
||||||
for _, file := range dir {
|
for _, file := range dir {
|
||||||
bodyAsBytes, err := ioutil.ReadFile(path.Join(tempPath, file.Name()))
|
bodyAsBytes, err := ioutil.ReadFile(filepath.Join(tempPath, file.Name()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue