mirror of
https://github.com/teacat/chaturbate-dvr.git
synced 2025-10-29 16:59:59 +00:00
Updated 0.94 Alpha
This commit is contained in:
parent
029f471477
commit
b5794ff71d
6
DEV.md
6
DEV.md
@ -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 &&
|
||||
|
||||
14
README-tw.md
14
README-tw.md
@ -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)
|
||||
```
|
||||
|
||||
## 中文對應
|
||||
|
||||
14
README.md
14
README.md
@ -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.
Binary file not shown.
Binary file not shown.
BIN
chaturbate-dvr
BIN
chaturbate-dvr
Binary file not shown.
2
go.mod
2
go.mod
@ -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
4
go.sum
@ -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
111
main.go
@ -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",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user