mirror of
https://github.com/teacat/chaturbate-dvr.git
synced 2025-10-29 16:59:59 +00:00
Fixed #55
This commit is contained in:
parent
2c5d2a984c
commit
153cf4f800
@ -10,7 +10,7 @@ For Chaturbate-**only**, private/ticket stream is **unsupported**.
|
|||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Download **`source code (zip)`** from **[Release](https://github.com/teacat/chaturbate-dvr/releases)** page. Unzip **`/bin`** folder and look up for executable that **fits your system**.
|
Download executable from **[Release](https://github.com/teacat/chaturbate-dvr/releases)** page.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -98,6 +98,7 @@ GLOBAL OPTIONS:
|
|||||||
--gui-username value, --gui-u value username for auth web (optional)
|
--gui-username value, --gui-u value username for auth web (optional)
|
||||||
--gui-password value, --gui-p value password for auth web (optional)
|
--gui-password value, --gui-p value password for auth web (optional)
|
||||||
--framerate value, -f value preferred framerate (default: 30)
|
--framerate value, -f value preferred framerate (default: 30)
|
||||||
|
--interval value, -i value minutes to check if the channel is online (default: 1)
|
||||||
--resolution value, -r value preferred resolution (default: 1080)
|
--resolution value, -r value preferred resolution (default: 1080)
|
||||||
--resolution-fallback value, --rf value fallback to 'up' (larger) or 'down' (smaller) resolution if preferred resolution is not available (default: "down")
|
--resolution-fallback value, --rf value fallback to 'up' (larger) or 'down' (smaller) resolution if preferred resolution is not available (default: "down")
|
||||||
--filename-pattern value, --fp value filename pattern for videos (default: "videos/{{.Username}}_{{.Year}}-{{.Month}}-{{.Day}}_{{.Hour}}-{{.Minute}}-{{.Second}}{{if .Sequence}}_{{.Sequence}}{{end}}")
|
--filename-pattern value, --fp value filename pattern for videos (default: "videos/{{.Username}}_{{.Year}}-{{.Month}}-{{.Day}}_{{.Hour}}-{{.Minute}}-{{.Second}}{{if .Sequence}}_{{.Sequence}}{{end}}")
|
||||||
|
|||||||
@ -26,6 +26,7 @@ type Channel struct {
|
|||||||
ChannelURL string
|
ChannelURL string
|
||||||
filenamePattern string
|
filenamePattern string
|
||||||
LastStreamedAt string
|
LastStreamedAt string
|
||||||
|
Interval int
|
||||||
Framerate int
|
Framerate int
|
||||||
Resolution int
|
Resolution int
|
||||||
ResolutionFallback string
|
ResolutionFallback string
|
||||||
@ -98,8 +99,8 @@ func (w *Channel) Run() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
w.log(logTypeInfo, "channel is offline, check again 1 min later")
|
w.log(logTypeInfo, "channel is offline, check again %d min(s) later", w.Interval)
|
||||||
<-time.After(1 * time.Minute) // 1 minute cooldown to check online status
|
<-time.After(time.Duration(w.Interval) * time.Minute) // minutes cooldown to check online status
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -31,6 +31,7 @@ type Config struct {
|
|||||||
ResolutionFallback string
|
ResolutionFallback string
|
||||||
SplitDuration int
|
SplitDuration int
|
||||||
SplitFilesize int
|
SplitFilesize int
|
||||||
|
Interval int
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manager
|
// Manager
|
||||||
@ -99,6 +100,7 @@ func (m *Manager) CreateChannel(conf *Config) error {
|
|||||||
Framerate: conf.Framerate,
|
Framerate: conf.Framerate,
|
||||||
Resolution: conf.Resolution,
|
Resolution: conf.Resolution,
|
||||||
ResolutionFallback: conf.ResolutionFallback,
|
ResolutionFallback: conf.ResolutionFallback,
|
||||||
|
Interval: conf.Interval,
|
||||||
LastStreamedAt: "-",
|
LastStreamedAt: "-",
|
||||||
SegmentDuration: 0,
|
SegmentDuration: 0,
|
||||||
SplitDuration: conf.SplitDuration,
|
SplitDuration: conf.SplitDuration,
|
||||||
@ -176,6 +178,7 @@ func (m *Manager) SaveChannels() error {
|
|||||||
FilenamePattern: v.filenamePattern,
|
FilenamePattern: v.filenamePattern,
|
||||||
SplitDuration: v.SplitDuration,
|
SplitDuration: v.SplitDuration,
|
||||||
SplitFilesize: v.SplitFilesize,
|
SplitFilesize: v.SplitFilesize,
|
||||||
|
Interval: v.Interval,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
b, err := json.MarshalIndent(configs, "", " ")
|
b, err := json.MarshalIndent(configs, "", " ")
|
||||||
|
|||||||
@ -21,6 +21,7 @@ type CreateChannelRequest struct {
|
|||||||
ResolutionFallback string `json:"resolution_fallback"`
|
ResolutionFallback string `json:"resolution_fallback"`
|
||||||
SplitDuration int `json:"split_duration"`
|
SplitDuration int `json:"split_duration"`
|
||||||
SplitFilesize int `json:"split_filesize"`
|
SplitFilesize int `json:"split_filesize"`
|
||||||
|
Interval int `json:"interval"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateChannelResponse struct {
|
type CreateChannelResponse struct {
|
||||||
@ -59,6 +60,7 @@ func (h *CreateChannelHandler) Handle(c *gin.Context) {
|
|||||||
FilenamePattern: req.FilenamePattern,
|
FilenamePattern: req.FilenamePattern,
|
||||||
SplitDuration: req.SplitDuration,
|
SplitDuration: req.SplitDuration,
|
||||||
SplitFilesize: req.SplitFilesize,
|
SplitFilesize: req.SplitFilesize,
|
||||||
|
Interval: req.Interval,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
c.AbortWithError(http.StatusInternalServerError, err)
|
c.AbortWithError(http.StatusInternalServerError, err)
|
||||||
return
|
return
|
||||||
|
|||||||
@ -22,6 +22,7 @@ type GetSettingsHandlerResponse struct {
|
|||||||
FilenamePattern string `json:"filename_pattern"`
|
FilenamePattern string `json:"filename_pattern"`
|
||||||
SplitDuration int `json:"split_duration"`
|
SplitDuration int `json:"split_duration"`
|
||||||
SplitFilesize int `json:"split_filesize"`
|
SplitFilesize int `json:"split_filesize"`
|
||||||
|
Interval int `json:"interval"`
|
||||||
LogLevel string `json:"log_level"`
|
LogLevel string `json:"log_level"`
|
||||||
Port string `json:"port"`
|
Port string `json:"port"`
|
||||||
GUI string `json:"gui"`
|
GUI string `json:"gui"`
|
||||||
@ -57,6 +58,7 @@ func (h *GetSettingsHandler) Handle(c *gin.Context) {
|
|||||||
FilenamePattern: h.cli.String("filename-pattern"),
|
FilenamePattern: h.cli.String("filename-pattern"),
|
||||||
SplitDuration: h.cli.Int("split-duration"),
|
SplitDuration: h.cli.Int("split-duration"),
|
||||||
SplitFilesize: h.cli.Int("split-filesize"),
|
SplitFilesize: h.cli.Int("split-filesize"),
|
||||||
|
Interval: h.cli.Int("interval"),
|
||||||
LogLevel: h.cli.String("log-level"),
|
LogLevel: h.cli.String("log-level"),
|
||||||
Port: h.cli.String("port"),
|
Port: h.cli.String("port"),
|
||||||
GUI: h.cli.String("gui"),
|
GUI: h.cli.String("gui"),
|
||||||
|
|||||||
@ -28,6 +28,7 @@ type ListChannelsResponseChannel struct {
|
|||||||
SplitDuration string `json:"split_duration"`
|
SplitDuration string `json:"split_duration"`
|
||||||
SegmentFilesize string `json:"segment_filesize"`
|
SegmentFilesize string `json:"segment_filesize"`
|
||||||
SplitFilesize string `json:"split_filesize"`
|
SplitFilesize string `json:"split_filesize"`
|
||||||
|
Interval int `json:"interval"`
|
||||||
IsOnline bool `json:"is_online"`
|
IsOnline bool `json:"is_online"`
|
||||||
IsPaused bool `json:"is_paused"`
|
IsPaused bool `json:"is_paused"`
|
||||||
Logs []string `json:"logs"`
|
Logs []string `json:"logs"`
|
||||||
@ -74,6 +75,7 @@ func (h *ListChannelsHandler) Handle(c *gin.Context) {
|
|||||||
SplitDuration: channel.SplitDurationStr(),
|
SplitDuration: channel.SplitDurationStr(),
|
||||||
SegmentFilesize: channel.SegmentFilesizeStr(),
|
SegmentFilesize: channel.SegmentFilesizeStr(),
|
||||||
SplitFilesize: channel.SplitFilesizeStr(),
|
SplitFilesize: channel.SplitFilesizeStr(),
|
||||||
|
Interval: channel.Interval,
|
||||||
IsOnline: channel.IsOnline,
|
IsOnline: channel.IsOnline,
|
||||||
IsPaused: channel.IsPaused,
|
IsPaused: channel.IsPaused,
|
||||||
Logs: channel.Logs,
|
Logs: channel.Logs,
|
||||||
|
|||||||
@ -122,6 +122,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<!-- / Field: Filename Pattern -->
|
<!-- / Field: Filename Pattern -->
|
||||||
|
|
||||||
|
<!-- Field: Check Interval -->
|
||||||
|
<input type="hidden" x-model="form_data.interval" />
|
||||||
|
<!-- / Field: Check Interval -->
|
||||||
|
|
||||||
<div class="ts-divider has-vertically-spaced-large"></div>
|
<div class="ts-divider has-vertically-spaced-large"></div>
|
||||||
|
|
||||||
<!-- Field: Splitting Options -->
|
<!-- Field: Splitting Options -->
|
||||||
|
|||||||
@ -11,6 +11,7 @@ function data() {
|
|||||||
filename_pattern: "{{.Username}}_{{.Year}}-{{.Month}}-{{.Day}}_{{.Hour}}-{{.Minute}}-{{.Second}}{{if .Sequence}}_{{.Sequence}}{{end}}",
|
filename_pattern: "{{.Username}}_{{.Year}}-{{.Month}}-{{.Day}}_{{.Hour}}-{{.Minute}}-{{.Second}}{{if .Sequence}}_{{.Sequence}}{{end}}",
|
||||||
split_filesize: 0,
|
split_filesize: 0,
|
||||||
split_duration: 0,
|
split_duration: 0,
|
||||||
|
interval: 1,
|
||||||
},
|
},
|
||||||
|
|
||||||
// openCreateDialog
|
// openCreateDialog
|
||||||
@ -46,7 +47,7 @@ function data() {
|
|||||||
this.error()
|
this.error()
|
||||||
return [null, true]
|
return [null, true]
|
||||||
}
|
}
|
||||||
return [(await resp.json()), false]
|
return [await resp.json(), false]
|
||||||
} catch {
|
} catch {
|
||||||
this.error()
|
this.error()
|
||||||
return [null, true]
|
return [null, true]
|
||||||
@ -83,6 +84,7 @@ function data() {
|
|||||||
filename_pattern: this.settings.filename_pattern,
|
filename_pattern: this.settings.filename_pattern,
|
||||||
split_filesize: this.settings.split_filesize.toString(),
|
split_filesize: this.settings.split_filesize.toString(),
|
||||||
split_duration: this.settings.split_duration.toString(),
|
split_duration: this.settings.split_duration.toString(),
|
||||||
|
interval: this.settings.interval.toString(),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -96,6 +98,7 @@ function data() {
|
|||||||
filename_pattern: this.form_data.filename_pattern,
|
filename_pattern: this.form_data.filename_pattern,
|
||||||
split_filesize: parseInt(this.form_data.split_filesize),
|
split_filesize: parseInt(this.form_data.split_filesize),
|
||||||
split_duration: parseInt(this.form_data.split_duration),
|
split_duration: parseInt(this.form_data.split_duration),
|
||||||
|
interval: parseInt(this.form_data.interval),
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -121,7 +124,6 @@ function data() {
|
|||||||
alert("The program is terminated, any error messages are safe to ignore.")
|
alert("The program is terminated, any error messages are safe to ignore.")
|
||||||
await this.call("terminate_program", {})
|
await this.call("terminate_program", {})
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// resumeChannel
|
// resumeChannel
|
||||||
@ -184,12 +186,14 @@ function data() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
downloadLogs(username) {
|
downloadLogs(username) {
|
||||||
var a = window.document.createElement('a');
|
var a = window.document.createElement("a")
|
||||||
a.href = window.URL.createObjectURL(new Blob([this.channels[this.channels.findIndex(ch => ch.username === username)].logs.join('\n')], { type: 'text/plain', oneTimeOnly: true }));
|
a.href = window.URL.createObjectURL(
|
||||||
|
new Blob([this.channels[this.channels.findIndex(ch => ch.username === username)].logs.join("\n")], { type: "text/plain", oneTimeOnly: true })
|
||||||
|
)
|
||||||
a.download = `${username}_logs.txt`
|
a.download = `${username}_logs.txt`
|
||||||
document.body.appendChild(a);
|
document.body.appendChild(a)
|
||||||
a.click();
|
a.click()
|
||||||
document.body.removeChild(a);
|
document.body.removeChild(a)
|
||||||
},
|
},
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -205,4 +209,4 @@ function data() {
|
|||||||
}, 1)
|
}, 1)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
9
main.go
9
main.go
@ -31,7 +31,7 @@ const logo = `
|
|||||||
func main() {
|
func main() {
|
||||||
app := &cli.App{
|
app := &cli.App{
|
||||||
Name: "chaturbate-dvr",
|
Name: "chaturbate-dvr",
|
||||||
Version: "1.0.4",
|
Version: "1.0.5",
|
||||||
Usage: "Records your favorite Chaturbate stream 😎🫵",
|
Usage: "Records your favorite Chaturbate stream 😎🫵",
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
@ -98,6 +98,12 @@ func main() {
|
|||||||
Usage: "port to expose the web interface and API",
|
Usage: "port to expose the web interface and API",
|
||||||
Value: "8080",
|
Value: "8080",
|
||||||
},
|
},
|
||||||
|
&cli.IntFlag{
|
||||||
|
Name: "interval",
|
||||||
|
Aliases: []string{"i"},
|
||||||
|
Usage: "minutes to check if the channel is online",
|
||||||
|
Value: 1,
|
||||||
|
},
|
||||||
//&cli.StringFlag{
|
//&cli.StringFlag{
|
||||||
// Name: "gui",
|
// Name: "gui",
|
||||||
// Usage: "enabling GUI, availables: 'no', 'web'",
|
// Usage: "enabling GUI, availables: 'no', 'web'",
|
||||||
@ -128,6 +134,7 @@ func start(c *cli.Context) error {
|
|||||||
FilenamePattern: c.String("filename-pattern"),
|
FilenamePattern: c.String("filename-pattern"),
|
||||||
SplitDuration: c.Int("split-duration"),
|
SplitDuration: c.Int("split-duration"),
|
||||||
SplitFilesize: c.Int("split-filesize"),
|
SplitFilesize: c.Int("split-filesize"),
|
||||||
|
Interval: c.Int("interval"),
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user