This commit is contained in:
bytedream 2021-08-19 23:42:41 +02:00
parent 291aae18f3
commit cc549c817f
4 changed files with 49 additions and 36 deletions

View file

@ -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

View file

@ -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
} }
jNum, err := strconv.Atoi(strings.Split(path.Base(filenames[j]), ".")[0]) defer os.Remove(f.Name())
if err != nil { f.Close()
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 {

View file

@ -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()

View file

@ -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
} }