mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
1b84c7e7ba | ||
|
21a4b2b797 | ||
|
5e96bca296 | ||
|
c78d797fe7 | ||
|
57596315e9 | ||
|
0d7887e9d2 | ||
|
978fd8977d | ||
|
4ab5901ba9 |
@ -3,7 +3,9 @@ FROM $BASE_IMAGE
|
|||||||
|
|
||||||
# latest working version with EGL: 111.0.5563.146, revert when resolved
|
# latest working version with EGL: 111.0.5563.146, revert when resolved
|
||||||
# 112.0.5615.49 fails: https://github.com/VirtualGL/virtualgl/issues/229
|
# 112.0.5615.49 fails: https://github.com/VirtualGL/virtualgl/issues/229
|
||||||
ARG SRC_URL="https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_111.0.5563.146-1_amd64.deb"
|
# google does not provide a direct link to the deb file anymore
|
||||||
|
# ARG SRC_URL="https://dl.google.com/linux/chrome/deb/pool/main/g/google-chrome-stable/google-chrome-stable_111.0.5563.146-1_amd64.deb"
|
||||||
|
ARG SRC_URL="https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb"
|
||||||
|
|
||||||
#
|
#
|
||||||
# install google chrome
|
# install google chrome
|
||||||
|
@ -313,7 +313,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
get clipboard_read_available() {
|
get clipboard_read_available() {
|
||||||
return 'clipboard' in navigator && typeof navigator.clipboard.readText === 'function'
|
return (
|
||||||
|
'clipboard' in navigator &&
|
||||||
|
typeof navigator.clipboard.readText === 'function' &&
|
||||||
|
// Firefox 122+ incorrectly reports that it can read the clipboard but it can't
|
||||||
|
// instead it hangs when reading clipboard, until user clicks on the page
|
||||||
|
// and the click itself is not handled by the page at all, also the clipboard
|
||||||
|
// reads always fail with "Clipboard read operation is not allowed."
|
||||||
|
navigator.userAgent.indexOf('Firefox') == -1
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
get clipboard_write_available() {
|
get clipboard_write_available() {
|
||||||
@ -630,7 +638,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
async syncClipboard() {
|
async syncClipboard() {
|
||||||
if (this.clipboard_read_available) {
|
if (this.clipboard_read_available && window.document.hasFocus()) {
|
||||||
try {
|
try {
|
||||||
const text = await navigator.clipboard.readText()
|
const text = await navigator.clipboard.readText()
|
||||||
if (this.clipboard !== text) {
|
if (this.clipboard !== text) {
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
- Added nvidia support for firefox.
|
- Added nvidia support for firefox.
|
||||||
- Added `?lang=<lang>` parameter to the URL, which will set the language of the interface (by @mbattista).
|
- Added `?lang=<lang>` parameter to the URL, which will set the language of the interface (by @mbattista).
|
||||||
- Added `?show_side=1` and `?mute_chat=1` parameter to the URL, for chat mute and show side (by @mbattista).
|
- Added `?show_side=1` and `?mute_chat=1` parameter to the URL, for chat mute and show side (by @mbattista).
|
||||||
|
- Added `NEKO_BROADCAST_AUTOSTART` to automatically start or do not start broadcasting when the room is created. By default, it is set to `true` because it was the previous behavior.
|
||||||
|
|
||||||
### Bugs
|
### Bugs
|
||||||
- Fix incorrect version sorting for chromium, microsoft-edge, opera and ungoogledchromium.
|
- Fix incorrect version sorting for chromium, microsoft-edge, opera and ungoogledchromium.
|
||||||
|
@ -107,9 +107,11 @@ nat1to1: <ip>
|
|||||||
#### `NEKO_BROADCAST_PIPELINE`:
|
#### `NEKO_BROADCAST_PIPELINE`:
|
||||||
- Makes it possible to create custom gstreamer pipeline used for broadcasting, strings `{url}`, `{device}` and `{display}` will be replaced.
|
- Makes it possible to create custom gstreamer pipeline used for broadcasting, strings `{url}`, `{device}` and `{display}` will be replaced.
|
||||||
#### `NEKO_BROADCAST_URL`:
|
#### `NEKO_BROADCAST_URL`:
|
||||||
- Set a default URL for broadcast streams. Setting this value will automatically enable broadcasting when n.eko starts. It can be disabled/changed later by admins in the GUI.
|
- Set a default URL for broadcast streams. It can be disabled/changed later by admins in the GUI.
|
||||||
- e.g. `rtmp://<your-server>:1935/ingest/<stream-key>`
|
- e.g. `rtmp://<your-server>:1935/ingest/<stream-key>`
|
||||||
|
#### `NEKO_BROADCAST_AUTOSTART`:
|
||||||
|
- Automatically start broadcasting when neko starts and broadcast_url is set.
|
||||||
|
- e.g. `true`
|
||||||
### Server
|
### Server
|
||||||
|
|
||||||
#### `NEKO_BIND`:
|
#### `NEKO_BIND`:
|
||||||
|
@ -22,7 +22,7 @@ type BroacastManagerCtx struct {
|
|||||||
started bool
|
started bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func broadcastNew(pipelineFn func(url string) (string, error), defaultUrl string) *BroacastManagerCtx {
|
func broadcastNew(pipelineFn func(url string) (string, error), url string, started bool) *BroacastManagerCtx {
|
||||||
logger := log.With().
|
logger := log.With().
|
||||||
Str("module", "capture").
|
Str("module", "capture").
|
||||||
Str("submodule", "broadcast").
|
Str("submodule", "broadcast").
|
||||||
@ -31,8 +31,8 @@ func broadcastNew(pipelineFn func(url string) (string, error), defaultUrl string
|
|||||||
return &BroacastManagerCtx{
|
return &BroacastManagerCtx{
|
||||||
logger: logger,
|
logger: logger,
|
||||||
pipelineFn: pipelineFn,
|
pipelineFn: pipelineFn,
|
||||||
url: defaultUrl,
|
url: url,
|
||||||
started: defaultUrl != "",
|
started: started && url != "",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ func New(desktop types.DesktopManager, config *config.Capture) *CaptureManagerCt
|
|||||||
// sinks
|
// sinks
|
||||||
broadcast: broadcastNew(func(url string) (string, error) {
|
broadcast: broadcastNew(func(url string) (string, error) {
|
||||||
return NewBroadcastPipeline(config.AudioDevice, config.Display, config.BroadcastPipeline, url)
|
return NewBroadcastPipeline(config.AudioDevice, config.Display, config.BroadcastPipeline, url)
|
||||||
}, config.BroadcastUrl),
|
}, config.BroadcastUrl, config.BroadcastAutostart),
|
||||||
audio: streamSinkNew(config.AudioCodec, func() (string, error) {
|
audio: streamSinkNew(config.AudioCodec, func() (string, error) {
|
||||||
return NewAudioPipeline(config.AudioCodec, config.AudioDevice, config.AudioPipeline, config.AudioBitrate)
|
return NewAudioPipeline(config.AudioCodec, config.AudioDevice, config.AudioPipeline, config.AudioBitrate)
|
||||||
}, "audio"),
|
}, "audio"),
|
||||||
|
@ -34,8 +34,9 @@ type Capture struct {
|
|||||||
AudioPipeline string
|
AudioPipeline string
|
||||||
|
|
||||||
// broadcast
|
// broadcast
|
||||||
BroadcastPipeline string
|
BroadcastPipeline string
|
||||||
BroadcastUrl string
|
BroadcastUrl string
|
||||||
|
BroadcastAutostart bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (Capture) Init(cmd *cobra.Command) error {
|
func (Capture) Init(cmd *cobra.Command) error {
|
||||||
@ -155,11 +156,16 @@ func (Capture) Init(cmd *cobra.Command) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.PersistentFlags().String("broadcast_url", "", "URL for broadcasting, setting this value will automatically enable broadcasting")
|
cmd.PersistentFlags().String("broadcast_url", "", "a default default URL for broadcast streams, can be disabled/changed later by admins in the GUI")
|
||||||
if err := viper.BindPFlag("broadcast_url", cmd.PersistentFlags().Lookup("broadcast_url")); err != nil {
|
if err := viper.BindPFlag("broadcast_url", cmd.PersistentFlags().Lookup("broadcast_url")); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmd.PersistentFlags().Bool("broadcast_autostart", true, "automatically start broadcasting when neko starts and broadcast_url is set")
|
||||||
|
if err := viper.BindPFlag("broadcast_autostart", cmd.PersistentFlags().Lookup("broadcast_autostart")); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,4 +253,5 @@ func (s *Capture) Set() {
|
|||||||
|
|
||||||
s.BroadcastPipeline = viper.GetString("broadcast_pipeline")
|
s.BroadcastPipeline = viper.GetString("broadcast_pipeline")
|
||||||
s.BroadcastUrl = viper.GetString("broadcast_url")
|
s.BroadcastUrl = viper.GetString("broadcast_url")
|
||||||
|
s.BroadcastAutostart = viper.GetBool("broadcast_autostart")
|
||||||
}
|
}
|
||||||
|
@ -46,9 +46,9 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
BORADCAST_STATUS = "broadcast/status"
|
BROADCAST_STATUS = "broadcast/status"
|
||||||
BORADCAST_CREATE = "broadcast/create"
|
BROADCAST_CREATE = "broadcast/create"
|
||||||
BORADCAST_DESTROY = "broadcast/destroy"
|
BROADCAST_DESTROY = "broadcast/destroy"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -175,7 +175,7 @@ func (h *MessageHandler) adminGive(id string, session types.Session, payload *me
|
|||||||
ID: id,
|
ID: id,
|
||||||
Target: payload.ID,
|
Target: payload.ID,
|
||||||
}, nil); err != nil {
|
}, nil); err != nil {
|
||||||
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.CONTROL_LOCKED)
|
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.CONTROL_GIVE)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,7 +207,7 @@ func (h *MessageHandler) adminMute(id string, session types.Session, payload *me
|
|||||||
Target: target.ID(),
|
Target: target.ID(),
|
||||||
ID: id,
|
ID: id,
|
||||||
}, nil); err != nil {
|
}, nil); err != nil {
|
||||||
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.ADMIN_UNMUTE)
|
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.ADMIN_MUTE)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ import (
|
|||||||
"m1k1o/neko/internal/types/message"
|
"m1k1o/neko/internal/types/message"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *MessageHandler) boradcastCreate(session types.Session, payload *message.BroadcastCreate) error {
|
func (h *MessageHandler) broadcastCreate(session types.Session, payload *message.BroadcastCreate) error {
|
||||||
broadcast := h.capture.Broadcast()
|
broadcast := h.capture.Broadcast()
|
||||||
|
|
||||||
if !session.Admin() {
|
if !session.Admin() {
|
||||||
@ -44,14 +44,14 @@ func (h *MessageHandler) boradcastCreate(session types.Session, payload *message
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.boradcastStatus(nil); err != nil {
|
if err := h.broadcastStatus(nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *MessageHandler) boradcastDestroy(session types.Session) error {
|
func (h *MessageHandler) broadcastDestroy(session types.Session) error {
|
||||||
broadcast := h.capture.Broadcast()
|
broadcast := h.capture.Broadcast()
|
||||||
|
|
||||||
if !session.Admin() {
|
if !session.Admin() {
|
||||||
@ -70,18 +70,18 @@ func (h *MessageHandler) boradcastDestroy(session types.Session) error {
|
|||||||
|
|
||||||
broadcast.Stop()
|
broadcast.Stop()
|
||||||
|
|
||||||
if err := h.boradcastStatus(nil); err != nil {
|
if err := h.broadcastStatus(nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *MessageHandler) boradcastStatus(session types.Session) error {
|
func (h *MessageHandler) broadcastStatus(session types.Session) error {
|
||||||
broadcast := h.capture.Broadcast()
|
broadcast := h.capture.Broadcast()
|
||||||
|
|
||||||
msg := message.BroadcastStatus{
|
msg := message.BroadcastStatus{
|
||||||
Event: event.BORADCAST_STATUS,
|
Event: event.BROADCAST_STATUS,
|
||||||
IsActive: broadcast.Started(),
|
IsActive: broadcast.Started(),
|
||||||
URL: broadcast.Url(),
|
URL: broadcast.Url(),
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ func (h *MessageHandler) boradcastStatus(session types.Session) error {
|
|||||||
// if no session, broadcast change
|
// if no session, broadcast change
|
||||||
if session == nil {
|
if session == nil {
|
||||||
if err := h.sessions.AdminBroadcast(msg, nil); err != nil {
|
if err := h.sessions.AdminBroadcast(msg, nil); err != nil {
|
||||||
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.BORADCAST_STATUS)
|
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.BROADCAST_STATUS)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +102,7 @@ func (h *MessageHandler) boradcastStatus(session types.Session) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := session.Send(msg); err != nil {
|
if err := session.Send(msg); err != nil {
|
||||||
h.logger.Warn().Err(err).Msgf("sending event %s has failed", event.BORADCAST_STATUS)
|
h.logger.Warn().Err(err).Msgf("sending event %s has failed", event.BROADCAST_STATUS)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ func (h *MessageHandler) chat(id string, session types.Session, payload *message
|
|||||||
Content: payload.Content,
|
Content: payload.Content,
|
||||||
ID: id,
|
ID: id,
|
||||||
}, nil); err != nil {
|
}, nil); err != nil {
|
||||||
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.CONTROL_RELEASE)
|
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.CHAT_MESSAGE)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -34,7 +34,7 @@ func (h *MessageHandler) chatEmote(id string, session types.Session, payload *me
|
|||||||
Emote: payload.Emote,
|
Emote: payload.Emote,
|
||||||
ID: id,
|
ID: id,
|
||||||
}, nil); err != nil {
|
}, nil); err != nil {
|
||||||
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.CONTROL_RELEASE)
|
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.CHAT_EMOTE)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -115,7 +115,7 @@ func (h *MessageHandler) controlGive(id string, session types.Session, payload *
|
|||||||
ID: id,
|
ID: id,
|
||||||
Target: payload.ID,
|
Target: payload.ID,
|
||||||
}, nil); err != nil {
|
}, nil); err != nil {
|
||||||
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.CONTROL_LOCKED)
|
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.CONTROL_GIVE)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,15 +148,15 @@ func (h *MessageHandler) Message(id string, raw []byte) error {
|
|||||||
return h.screenSet(id, session, payload)
|
return h.screenSet(id, session, payload)
|
||||||
}), "%s failed", header.Event)
|
}), "%s failed", header.Event)
|
||||||
|
|
||||||
// Boradcast Events
|
// Broadcast Events
|
||||||
case event.BORADCAST_CREATE:
|
case event.BROADCAST_CREATE:
|
||||||
payload := &message.BroadcastCreate{}
|
payload := &message.BroadcastCreate{}
|
||||||
return errors.Wrapf(
|
return errors.Wrapf(
|
||||||
utils.Unmarshal(payload, raw, func() error {
|
utils.Unmarshal(payload, raw, func() error {
|
||||||
return h.boradcastCreate(session, payload)
|
return h.broadcastCreate(session, payload)
|
||||||
}), "%s failed", header.Event)
|
}), "%s failed", header.Event)
|
||||||
case event.BORADCAST_DESTROY:
|
case event.BROADCAST_DESTROY:
|
||||||
return errors.Wrapf(h.boradcastDestroy(session), "%s failed", header.Event)
|
return errors.Wrapf(h.broadcastDestroy(session), "%s failed", header.Event)
|
||||||
|
|
||||||
// Admin Events
|
// Admin Events
|
||||||
case event.ADMIN_LOCK:
|
case event.ADMIN_LOCK:
|
||||||
|
@ -30,7 +30,7 @@ func (h *MessageHandler) SessionCreated(id string, session types.Session) error
|
|||||||
}
|
}
|
||||||
|
|
||||||
// send broadcast status if admin
|
// send broadcast status if admin
|
||||||
if err := h.boradcastStatus(session); err != nil {
|
if err := h.broadcastStatus(session); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@ func (h *MessageHandler) SessionConnected(id string, session types.Session) erro
|
|||||||
Event: event.MEMBER_CONNECTED,
|
Event: event.MEMBER_CONNECTED,
|
||||||
Member: session.Member(),
|
Member: session.Member(),
|
||||||
}, nil); err != nil {
|
}, nil); err != nil {
|
||||||
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.CONTROL_RELEASE)
|
h.logger.Warn().Err(err).Msgf("broadcasting event %s has failed", event.MEMBER_CONNECTED)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user