Updated 0.94 Alpha

This commit is contained in:
Yami Odymel 2023-10-01 18:31:08 +08:00
parent 029f471477
commit b5794ff71d
No known key found for this signature in database
GPG Key ID: 68E469836934DB36
13 changed files with 135 additions and 16 deletions

6
DEV.md
View File

@ -1,6 +1,6 @@
GOOS=windows GOARCH=amd64 go build -o bin/windows &&
GOOS=darwin GOARCH=amd64 go build -o bin/darwin &&
GOOS=linux GOARCH=amd64 go build -o bin/linux
GOOS=windows GOARCH=amd64 go build -o bin/windows/chatubrate-dvr &&
GOOS=darwin GOARCH=amd64 go build -o bin/darwin/chatubrate-dvr &&
GOOS=linux GOARCH=amd64 go build -o bin/linux/chatubrate-dvr
GOOS=windows GOARCH=arm64 go build -o bin/arm64/windows/chatubrate-dvr &&
GOOS=darwin GOARCH=arm64 go build -o bin/arm64/darwin/chatubrate-dvr &&

View File

@ -37,8 +37,6 @@ Y8888D' YP 88 YD
## 說明
影片畫質永遠是以最高為優先,目前沒辦法更改(懶得寫成一個選項)。
```bash
NAME:
chaturbate-dvr - watching a specified chaturbate channel and auto saves the stream as local file
@ -50,10 +48,14 @@ COMMANDS:
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--username value, -u value channel username to watching
--interval value, -i value minutes to check if a channel goes online or not (default: 1)
--strip value, -s value MB sizes to split the video into chunks (default: 0)
--help, -h show help (default: false)
--username value, -u value channel username to watching
--interval value, -i value minutes to check if a channel goes online or not (default: 1)
--strip value, -s value MB sizes to split the video into chunks (default: 0)
--resolution 240, -r 240 Video resolution, could be 240, `480`, `540`, `720`, `1080` (default: "1080")
--resolution-fallback up, --rf up Looking for larger or smaller resolution (up for larger, `down` for smaller) if a specified resolution was not found (default: "down")
--fps value, -f value Preferred framerate, only works if steaming source supports it, otherwise it will always be 30 FPS (default: "60")
--help, -h show help (default: false)
--version, -v print the version (default: false)
```
## 中文對應

View File

@ -39,8 +39,6 @@ Y8888D' YP 88 YD
## Help
The video quality is always the highest as possible, you cannot change it (too lazy to make it as an option).
```bash
NAME:
chaturbate-dvr - watching a specified chaturbate channel and auto saves the stream as local file
@ -52,8 +50,12 @@ COMMANDS:
help, h Shows a list of commands or help for one command
GLOBAL OPTIONS:
--username value, -u value channel username to watching
--interval value, -i value minutes to check if a channel goes online or not (default: 1)
--strip value, -s value MB sizes to split the video into chunks (default: 0)
--help, -h show help (default: false)
--username value, -u value channel username to watching
--interval value, -i value minutes to check if a channel goes online or not (default: 1)
--strip value, -s value MB sizes to split the video into chunks (default: 0)
--resolution 240, -r 240 Video resolution, could be 240, `480`, `540`, `720`, `1080` (default: "1080")
--resolution-fallback up, --rf up Looking for larger or smaller resolution (up for larger, `down` for smaller) if a specified resolution was not found (default: "down")
--fps value, -f value Preferred framerate, only works if steaming source supports it, otherwise it will always be 30 FPS (default: "60")
--help, -h show help (default: false)
--version, -v print the version (default: false)
```

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

2
go.mod
View File

@ -14,8 +14,10 @@ require (
github.com/elazarl/goproxy v0.0.0-20210801061803-8e322dfb79c4 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/russross/blackfriday/v2 v2.0.1 // indirect
github.com/samber/lo v1.38.1 // indirect
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
github.com/smartystreets/goconvey v1.7.2 // indirect
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 // indirect
golang.org/x/net v0.0.0-20211109214657-ef0fda0de508 // indirect
moul.io/http2curl v1.0.0 // indirect
)

4
go.sum
View File

@ -21,6 +21,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/rogpeppe/go-charset v0.0.0-20180617210344-2471d30d28b4/go.mod h1:qgYeAmZ5ZIpBWTGllZSQnw97Dj+woV0toclVaRGI8pc=
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM=
github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA=
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs=
@ -30,6 +32,8 @@ github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17 h1:3MTrJm4PyNL9NBqvYDSj3DHl46qQakyfqfWo4jgfaEM=
golang.org/x/exp v0.0.0-20220303212507-bbda1eaf7a17/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE=
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20211109214657-ef0fda0de508 h1:v3NKo+t/Kc3EASxaKZ82lwK6mCf4ZeObQBduYFZHo7c=
golang.org/x/net v0.0.0-20211109214657-ef0fda0de508/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=

111
main.go
View File

@ -15,6 +15,7 @@ import (
"time"
"github.com/TwiN/go-color"
"github.com/samber/lo"
"github.com/grafov/m3u8"
"github.com/parnurzeal/gorequest"
@ -44,6 +45,15 @@ var stripLimit int
// stripQuota represents how many Bytes left til the next video chunk stripping.
var stripQuota int
// preferredFPS represents the preferred framerate.
var preferredFPS string
// preferredResolution represents the preferred resolution, e.g. `240`, `480`, `540`, `720`, `1080`.
var preferredResolution string
// preferredResolutionFallback represents the preferred resolution fallback, `up`, `down` or `no`.
var preferredResolutionFallback string
// path save video
const savePath = "video"
@ -128,7 +138,83 @@ func parseHLSSource(url string, baseURL string) string {
if !ok {
return ""
}
return fmt.Sprintf("%s%s", baseURL, master.Variants[len(master.Variants)-1].URI)
resolutions := make(map[string][]string)
resolutionInts := []string{}
for _, v := range master.Variants {
resStr := strings.Split(v.Resolution, "x")
resolutionInts = append(resolutionInts, resStr[1])
// If the resolution exists in local, it might be a higher framerate source, store it for later use
if _, ok := resolutions[resStr[1]]; ok {
resolutions[resStr[1]] = append(resolutions[resStr[1]], v.URI)
continue
}
if strings.Contains(v.Name, "FPS:60.0") {
if _, ok := resolutions[resStr[1]]; !ok {
resolutions[resStr[1]] = []string{"", v.URI} // The video has no 30 FPS, we fill it with an empty URI
} else {
resolutions[resStr[1]] = []string{v.URI}
}
} else {
resolutions[resStr[1]] = []string{v.URI}
}
}
log.Printf("Found available resolutions: %s", strings.TrimPrefix(lo.Reduce(resolutionInts, func(prev string, cur string, _ int) string {
return fmt.Sprintf("%s, %s", prev, cur)
}, ""), ", "))
pickedResolution, ok := resolutions[preferredResolution]
if !ok {
var comparison []string
if preferredResolutionFallback == "down" {
comparison = lo.Reverse(lo.Map(resolutionInts, func(v string, _ int) string { return v }))
} else {
comparison = resolutionInts
}
fallbackResolution, ok := lo.Find(comparison, func(v string) bool {
sizeInt, _ := strconv.Atoi(v)
prefInt, _ := strconv.Atoi(preferredResolution)
//
if preferredResolutionFallback == "down" {
return sizeInt < prefInt
} else {
return sizeInt > prefInt
}
})
if ok {
pickedResolution = resolutions[fallbackResolution]
log.Printf("Preferred video resolution %sp not found, use %sp instead.", preferredResolution, fallbackResolution)
} else {
if preferredResolutionFallback == "down" {
pickedResolution = resolutions[resolutionInts[0]]
log.Printf("No fallback video resolution was found, use worse quality %sp instead.", resolutionInts[0])
} else {
pickedResolution = resolutions[resolutionInts[len(resolutionInts)-1]]
log.Printf("No fallback video resolution was found, use best quality %sp instead.", resolutionInts[len(resolutionInts)-1])
}
}
} else {
log.Printf("Fetching video resolution in %sp.", preferredResolution)
}
var uri string
if preferredFPS == "60" && len(pickedResolution) > 1 {
log.Printf("Fetching video in 60 FPS.")
uri = pickedResolution[1]
} else {
log.Printf("Fetching video in 30 FPS.")
uri = pickedResolution[0]
if uri == "" {
log.Printf("The video has no 30 FPS, use 60 FPS instead.")
uri = pickedResolution[1]
}
}
return fmt.Sprintf("%s%s", baseURL, uri)
}
// parseM3U8Source gets the current segment list, the channel might goes offline if 403 was returned.
@ -328,6 +414,10 @@ func endpoint(c *cli.Context) error {
stripLimit = c.Int("strip") * 1024 * 1024
stripQuota = c.Int("strip") * 1024 * 1024
//
preferredFPS = c.String("fps")
preferredResolution = c.String("resolution")
preferredResolutionFallback = c.String("resolution-fallback")
//
fmt.Println(" .o88b. db db .d8b. d888888b db db d8888b. d8888b. .d8b. d888888b d88888b")
fmt.Println("d8P Y8 88 88 d8' `8b `~~88~~' 88 88 88 `8D 88 `8D d8' `8b `~~88~~' 88'")
@ -370,6 +460,7 @@ func endpoint(c *cli.Context) error {
func main() {
app := &cli.App{
Version: "0.94 Alpha",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "username",
@ -389,6 +480,24 @@ func main() {
Value: 0,
Usage: "MB sizes to split the video into chunks",
},
&cli.StringFlag{
Name: "resolution",
Aliases: []string{"r"},
Value: "1080",
Usage: "Video resolution, could be `240`, `480`, `540`, `720`, `1080`",
},
&cli.StringFlag{
Name: "resolution-fallback",
Aliases: []string{"rf"},
Value: "down",
Usage: "Looking for larger or smaller resolution (`up` for larger, `down` for smaller) if a specified resolution was not found",
},
&cli.StringFlag{
Name: "fps",
Aliases: []string{"f"},
Value: "60",
Usage: "Preferred framerate, only works if steaming source supports it, otherwise it will always be 30 FPS",
},
},
Name: "chaturbate-dvr",
Usage: "watching a specified chaturbate channel and auto saves the stream as local file",