node build fixed
This commit is contained in:
567
seanime-2.9.10/internal/debrid/client/stream.go
Normal file
567
seanime-2.9.10/internal/debrid/client/stream.go
Normal file
@@ -0,0 +1,567 @@
|
||||
package debrid_client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"seanime/internal/database/db_bridge"
|
||||
"seanime/internal/debrid/debrid"
|
||||
"seanime/internal/directstream"
|
||||
"seanime/internal/events"
|
||||
hibiketorrent "seanime/internal/extension/hibike/torrent"
|
||||
"seanime/internal/hook"
|
||||
"seanime/internal/library/playbackmanager"
|
||||
"seanime/internal/util"
|
||||
"strconv"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/samber/mo"
|
||||
)
|
||||
|
||||
type (
|
||||
StreamManager struct {
|
||||
repository *Repository
|
||||
currentTorrentItemId string
|
||||
downloadCtxCancelFunc context.CancelFunc
|
||||
|
||||
currentStreamUrl string
|
||||
|
||||
playbackSubscriberCtxCancelFunc context.CancelFunc
|
||||
}
|
||||
|
||||
StreamPlaybackType string
|
||||
|
||||
StreamStatus string
|
||||
|
||||
StreamState struct {
|
||||
Status StreamStatus `json:"status"`
|
||||
TorrentName string `json:"torrentName"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
StartStreamOptions struct {
|
||||
MediaId int
|
||||
EpisodeNumber int // RELATIVE Episode number to identify the file
|
||||
AniDBEpisode string // Anizip episode
|
||||
Torrent *hibiketorrent.AnimeTorrent // Selected torrent
|
||||
FileId string // File ID or index
|
||||
FileIndex *int // Index of the file to stream (Manual selection)
|
||||
UserAgent string
|
||||
ClientId string
|
||||
PlaybackType StreamPlaybackType
|
||||
AutoSelect bool
|
||||
}
|
||||
|
||||
CancelStreamOptions struct {
|
||||
// Whether to remove the torrent from the debrid service
|
||||
RemoveTorrent bool `json:"removeTorrent"`
|
||||
}
|
||||
)
|
||||
|
||||
const (
|
||||
StreamStatusDownloading StreamStatus = "downloading"
|
||||
StreamStatusReady StreamStatus = "ready"
|
||||
StreamStatusFailed StreamStatus = "failed"
|
||||
StreamStatusStarted StreamStatus = "started"
|
||||
)
|
||||
|
||||
func NewStreamManager(repository *Repository) *StreamManager {
|
||||
return &StreamManager{
|
||||
repository: repository,
|
||||
currentTorrentItemId: "",
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const (
|
||||
PlaybackTypeNone StreamPlaybackType = "none"
|
||||
PlaybackTypeNoneAndAwait StreamPlaybackType = "noneAndAwait"
|
||||
PlaybackTypeDefault StreamPlaybackType = "default"
|
||||
PlaybackTypeNativePlayer StreamPlaybackType = "nativeplayer"
|
||||
PlaybackTypeExternalPlayer StreamPlaybackType = "externalPlayerLink"
|
||||
)
|
||||
|
||||
// startStream is called by the client to start streaming a torrent
|
||||
func (s *StreamManager) startStream(ctx context.Context, opts *StartStreamOptions) (err error) {
|
||||
defer util.HandlePanicInModuleWithError("debrid/client/StartStream", &err)
|
||||
|
||||
s.repository.previousStreamOptions = mo.Some(opts)
|
||||
|
||||
s.repository.logger.Info().
|
||||
Str("clientId", opts.ClientId).
|
||||
Any("playbackType", opts.PlaybackType).
|
||||
Int("mediaId", opts.MediaId).Msgf("debridstream: Starting stream for episode %s", opts.AniDBEpisode)
|
||||
|
||||
// Cancel the download context if it's running
|
||||
if s.downloadCtxCancelFunc != nil {
|
||||
s.downloadCtxCancelFunc()
|
||||
s.downloadCtxCancelFunc = nil
|
||||
}
|
||||
|
||||
if s.playbackSubscriberCtxCancelFunc != nil {
|
||||
s.playbackSubscriberCtxCancelFunc()
|
||||
s.playbackSubscriberCtxCancelFunc = nil
|
||||
}
|
||||
|
||||
provider, err := s.repository.GetProvider()
|
||||
if err != nil {
|
||||
return fmt.Errorf("debridstream: Failed to start stream: %w", err)
|
||||
}
|
||||
|
||||
s.repository.wsEventManager.SendEvent(events.ShowIndefiniteLoader, "debridstream")
|
||||
//defer func() {
|
||||
// s.repository.wsEventManager.SendEvent(events.HideIndefiniteLoader, "debridstream")
|
||||
//}()
|
||||
|
||||
if opts.PlaybackType == PlaybackTypeNativePlayer {
|
||||
s.repository.directStreamManager.PrepareNewStream(opts.ClientId, "Selecting torrent...")
|
||||
}
|
||||
|
||||
//
|
||||
// Get the media info
|
||||
//
|
||||
media, _, err := s.getMediaInfo(ctx, opts.MediaId)
|
||||
if err != nil {
|
||||
s.repository.wsEventManager.SendEvent(events.HideIndefiniteLoader, "debridstream")
|
||||
return err
|
||||
}
|
||||
|
||||
episodeNumber := opts.EpisodeNumber
|
||||
aniDbEpisode := strconv.Itoa(episodeNumber)
|
||||
|
||||
selectedTorrent := opts.Torrent
|
||||
fileId := opts.FileId
|
||||
|
||||
if opts.AutoSelect {
|
||||
|
||||
s.repository.wsEventManager.SendEvent(events.DebridStreamState, StreamState{
|
||||
Status: StreamStatusDownloading,
|
||||
TorrentName: "-",
|
||||
Message: "Selecting best torrent...",
|
||||
})
|
||||
|
||||
st, fi, err := s.repository.findBestTorrent(provider, media, opts.EpisodeNumber)
|
||||
if err != nil {
|
||||
s.repository.wsEventManager.SendEvent(events.DebridStreamState, StreamState{
|
||||
Status: StreamStatusFailed,
|
||||
TorrentName: "-",
|
||||
Message: fmt.Sprintf("Failed to select best torrent, %v", err),
|
||||
})
|
||||
s.repository.wsEventManager.SendEvent(events.HideIndefiniteLoader, "debridstream")
|
||||
return fmt.Errorf("debridstream: Failed to start stream: %w", err)
|
||||
}
|
||||
selectedTorrent = st
|
||||
fileId = fi
|
||||
} else {
|
||||
// Manual selection
|
||||
if selectedTorrent == nil {
|
||||
s.repository.wsEventManager.SendEvent(events.HideIndefiniteLoader, "debridstream")
|
||||
return fmt.Errorf("debridstream: Failed to start stream, no torrent provided")
|
||||
}
|
||||
|
||||
s.repository.wsEventManager.SendEvent(events.DebridStreamState, StreamState{
|
||||
Status: StreamStatusDownloading,
|
||||
TorrentName: selectedTorrent.Name,
|
||||
Message: "Analyzing selected torrent...",
|
||||
})
|
||||
|
||||
// If no fileId is provided, we need to analyze the torrent to find the correct file
|
||||
if fileId == "" {
|
||||
var chosenFileIndex *int
|
||||
if opts.FileIndex != nil {
|
||||
chosenFileIndex = opts.FileIndex
|
||||
}
|
||||
st, fi, err := s.repository.findBestTorrentFromManualSelection(provider, selectedTorrent, media, opts.EpisodeNumber, chosenFileIndex)
|
||||
if err != nil {
|
||||
s.repository.wsEventManager.SendEvent(events.DebridStreamState, StreamState{
|
||||
Status: StreamStatusFailed,
|
||||
TorrentName: selectedTorrent.Name,
|
||||
Message: fmt.Sprintf("Failed to analyze torrent, %v", err),
|
||||
})
|
||||
s.repository.wsEventManager.SendEvent(events.HideIndefiniteLoader, "debridstream")
|
||||
return fmt.Errorf("debridstream: Failed to analyze torrent: %w", err)
|
||||
}
|
||||
selectedTorrent = st
|
||||
fileId = fi
|
||||
}
|
||||
}
|
||||
|
||||
if selectedTorrent == nil {
|
||||
s.repository.wsEventManager.SendEvent(events.HideIndefiniteLoader, "debridstream")
|
||||
return fmt.Errorf("debridstream: Failed to start stream, no torrent provided")
|
||||
}
|
||||
|
||||
s.repository.wsEventManager.SendEvent(events.DebridStreamState, StreamState{
|
||||
Status: StreamStatusDownloading,
|
||||
TorrentName: selectedTorrent.Name,
|
||||
Message: "Adding torrent...",
|
||||
})
|
||||
|
||||
// Add the torrent to the debrid service
|
||||
torrentItemId, err := provider.AddTorrent(debrid.AddTorrentOptions{
|
||||
MagnetLink: selectedTorrent.MagnetLink,
|
||||
InfoHash: selectedTorrent.InfoHash,
|
||||
SelectFileId: fileId, // RD-only, download only the selected file
|
||||
})
|
||||
if err != nil {
|
||||
s.repository.wsEventManager.SendEvent(events.DebridStreamState, StreamState{
|
||||
Status: StreamStatusFailed,
|
||||
TorrentName: selectedTorrent.Name,
|
||||
Message: fmt.Sprintf("Failed to add torrent, %v", err),
|
||||
})
|
||||
s.repository.wsEventManager.SendEvent(events.HideIndefiniteLoader, "debridstream")
|
||||
return fmt.Errorf("debridstream: Failed to add torrent: %w", err)
|
||||
}
|
||||
|
||||
time.Sleep(1 * time.Second)
|
||||
|
||||
// Save the current torrent item id
|
||||
s.currentTorrentItemId = torrentItemId
|
||||
ctx, cancelCtx := context.WithCancel(context.Background())
|
||||
s.downloadCtxCancelFunc = cancelCtx
|
||||
|
||||
readyCh := make(chan struct{})
|
||||
readyOnce := sync.Once{}
|
||||
ready := func() {
|
||||
readyOnce.Do(func() {
|
||||
close(readyCh)
|
||||
})
|
||||
}
|
||||
|
||||
// Launch a goroutine that will listen to the added torrent's status
|
||||
go func(ctx context.Context) {
|
||||
defer util.HandlePanicInModuleThen("debrid/client/StartStream", func() {})
|
||||
defer func() {
|
||||
s.repository.wsEventManager.SendEvent(events.HideIndefiniteLoader, "debridstream")
|
||||
}()
|
||||
|
||||
defer func() {
|
||||
// Cancel the context
|
||||
if s.downloadCtxCancelFunc != nil {
|
||||
s.downloadCtxCancelFunc()
|
||||
s.downloadCtxCancelFunc = nil
|
||||
}
|
||||
}()
|
||||
|
||||
s.repository.logger.Debug().Msg("debridstream: Listening to torrent status")
|
||||
|
||||
s.repository.wsEventManager.SendEvent(events.DebridStreamState, StreamState{
|
||||
Status: StreamStatusDownloading,
|
||||
TorrentName: selectedTorrent.Name,
|
||||
Message: fmt.Sprintf("Downloading torrent..."),
|
||||
})
|
||||
|
||||
itemCh := make(chan debrid.TorrentItem, 1)
|
||||
|
||||
go func() {
|
||||
for item := range itemCh {
|
||||
if opts.PlaybackType == PlaybackTypeNativePlayer {
|
||||
s.repository.directStreamManager.PrepareNewStream(opts.ClientId, fmt.Sprintf("Awaiting stream: %d%%", item.CompletionPercentage))
|
||||
}
|
||||
|
||||
s.repository.wsEventManager.SendEvent(events.DebridStreamState, StreamState{
|
||||
Status: StreamStatusDownloading,
|
||||
TorrentName: item.Name,
|
||||
Message: fmt.Sprintf("Downloading torrent: %d%%", item.CompletionPercentage),
|
||||
})
|
||||
}
|
||||
}()
|
||||
|
||||
// Await the stream URL
|
||||
// For Torbox, this will wait until the entire torrent is downloaded
|
||||
streamUrl, err := provider.GetTorrentStreamUrl(ctx, debrid.StreamTorrentOptions{
|
||||
ID: torrentItemId,
|
||||
FileId: fileId,
|
||||
}, itemCh)
|
||||
|
||||
go func() {
|
||||
close(itemCh)
|
||||
}()
|
||||
|
||||
if ctx.Err() != nil {
|
||||
s.repository.logger.Debug().Msg("debridstream: Context cancelled, stopping stream")
|
||||
ready()
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
s.repository.logger.Err(err).Msg("debridstream: Failed to get stream URL")
|
||||
if !errors.Is(err, context.Canceled) {
|
||||
s.repository.wsEventManager.SendEvent(events.DebridStreamState, StreamState{
|
||||
Status: StreamStatusFailed,
|
||||
TorrentName: selectedTorrent.Name,
|
||||
Message: fmt.Sprintf("Failed to get stream URL, %v", err),
|
||||
})
|
||||
}
|
||||
ready()
|
||||
return
|
||||
}
|
||||
|
||||
skipCheckEvent := &DebridSkipStreamCheckEvent{
|
||||
StreamURL: streamUrl,
|
||||
Retries: 4,
|
||||
RetryDelay: 8,
|
||||
}
|
||||
_ = hook.GlobalHookManager.OnDebridSkipStreamCheck().Trigger(skipCheckEvent)
|
||||
streamUrl = skipCheckEvent.StreamURL
|
||||
|
||||
// Default prevented, we check if we can stream the file
|
||||
if skipCheckEvent.DefaultPrevented {
|
||||
s.repository.logger.Debug().Msg("debridstream: Stream URL received, checking stream file")
|
||||
s.repository.wsEventManager.SendEvent(events.DebridStreamState, StreamState{
|
||||
Status: StreamStatusDownloading,
|
||||
TorrentName: selectedTorrent.Name,
|
||||
Message: "Checking stream file...",
|
||||
})
|
||||
|
||||
retries := 0
|
||||
|
||||
streamUrlCheckLoop:
|
||||
for { // Retry loop for a total of 4 times (32 seconds)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
s.repository.logger.Debug().Msg("debridstream: Context cancelled, stopping stream")
|
||||
return
|
||||
default:
|
||||
// Check if we can stream the URL
|
||||
if canStream, reason := CanStream(streamUrl); !canStream {
|
||||
if retries >= skipCheckEvent.Retries {
|
||||
s.repository.logger.Error().Msg("debridstream: Cannot stream the file")
|
||||
|
||||
s.repository.wsEventManager.SendEvent(events.DebridStreamState, StreamState{
|
||||
Status: StreamStatusFailed,
|
||||
TorrentName: selectedTorrent.Name,
|
||||
Message: fmt.Sprintf("Cannot stream this file: %s", reason),
|
||||
})
|
||||
return
|
||||
}
|
||||
s.repository.logger.Warn().Msg("debridstream: Rechecking stream file in 8 seconds")
|
||||
s.repository.wsEventManager.SendEvent(events.DebridStreamState, StreamState{
|
||||
Status: StreamStatusDownloading,
|
||||
TorrentName: selectedTorrent.Name,
|
||||
Message: "Checking stream file...",
|
||||
})
|
||||
retries++
|
||||
time.Sleep(time.Duration(skipCheckEvent.RetryDelay) * time.Second)
|
||||
continue
|
||||
}
|
||||
break streamUrlCheckLoop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
s.repository.logger.Debug().Msg("debridstream: Stream is ready")
|
||||
|
||||
// Signal to the client that the torrent is ready to stream
|
||||
s.repository.wsEventManager.SendEvent(events.DebridStreamState, StreamState{
|
||||
Status: StreamStatusReady,
|
||||
TorrentName: selectedTorrent.Name,
|
||||
Message: "Ready to stream the file",
|
||||
})
|
||||
|
||||
if ctx.Err() != nil {
|
||||
s.repository.logger.Debug().Msg("debridstream: Context cancelled, stopping stream")
|
||||
ready()
|
||||
return
|
||||
}
|
||||
|
||||
windowTitle := media.GetPreferredTitle()
|
||||
if !media.IsMovieOrSingleEpisode() {
|
||||
windowTitle += fmt.Sprintf(" - Episode %s", aniDbEpisode)
|
||||
}
|
||||
|
||||
event := &DebridSendStreamToMediaPlayerEvent{
|
||||
WindowTitle: windowTitle,
|
||||
StreamURL: streamUrl,
|
||||
Media: media.ToBaseAnime(),
|
||||
AniDbEpisode: aniDbEpisode,
|
||||
PlaybackType: string(opts.PlaybackType),
|
||||
}
|
||||
err = hook.GlobalHookManager.OnDebridSendStreamToMediaPlayer().Trigger(event)
|
||||
if err != nil {
|
||||
s.repository.logger.Err(err).Msg("debridstream: Failed to send stream to media player")
|
||||
}
|
||||
windowTitle = event.WindowTitle
|
||||
streamUrl = event.StreamURL
|
||||
media := event.Media
|
||||
aniDbEpisode := event.AniDbEpisode
|
||||
playbackType := StreamPlaybackType(event.PlaybackType)
|
||||
|
||||
if event.DefaultPrevented {
|
||||
s.repository.logger.Debug().Msg("debridstream: Stream prevented by hook")
|
||||
ready()
|
||||
return
|
||||
}
|
||||
|
||||
s.currentStreamUrl = streamUrl
|
||||
|
||||
switch playbackType {
|
||||
case PlaybackTypeNone:
|
||||
// No playback type selected, just signal to the client that the stream is ready
|
||||
s.repository.wsEventManager.SendEvent(events.DebridStreamState, StreamState{
|
||||
Status: StreamStatusReady,
|
||||
TorrentName: selectedTorrent.Name,
|
||||
Message: "External player link sent",
|
||||
})
|
||||
case PlaybackTypeNoneAndAwait:
|
||||
// No playback type selected, just signal to the client that the stream is ready
|
||||
s.repository.wsEventManager.SendEvent(events.DebridStreamState, StreamState{
|
||||
Status: StreamStatusReady,
|
||||
TorrentName: selectedTorrent.Name,
|
||||
Message: "External player link sent",
|
||||
})
|
||||
ready()
|
||||
|
||||
case PlaybackTypeDefault:
|
||||
//
|
||||
// Start the stream
|
||||
//
|
||||
s.repository.logger.Debug().Msg("debridstream: Starting the media player")
|
||||
|
||||
s.repository.wsEventManager.SendEvent(events.InfoToast, "Sending stream to media player...")
|
||||
s.repository.wsEventManager.SendEvent(events.ShowIndefiniteLoader, "debridstream")
|
||||
|
||||
var playbackSubscriberCtx context.Context
|
||||
playbackSubscriberCtx, s.playbackSubscriberCtxCancelFunc = context.WithCancel(context.Background())
|
||||
playbackSubscriber := s.repository.playbackManager.SubscribeToPlaybackStatus("debridstream")
|
||||
|
||||
// Sends the stream to the media player
|
||||
// DEVNOTE: Events are handled by the torrentstream.Repository module
|
||||
err = s.repository.playbackManager.StartStreamingUsingMediaPlayer(windowTitle, &playbackmanager.StartPlayingOptions{
|
||||
Payload: streamUrl,
|
||||
UserAgent: opts.UserAgent,
|
||||
ClientId: opts.ClientId,
|
||||
}, media, aniDbEpisode)
|
||||
if err != nil {
|
||||
go s.repository.playbackManager.UnsubscribeFromPlaybackStatus("debridstream")
|
||||
if s.playbackSubscriberCtxCancelFunc != nil {
|
||||
s.playbackSubscriberCtxCancelFunc()
|
||||
s.playbackSubscriberCtxCancelFunc = nil
|
||||
}
|
||||
// Failed to start the stream, we'll drop the torrents and stop the server
|
||||
s.repository.wsEventManager.SendEvent(events.DebridStreamState, StreamState{
|
||||
Status: StreamStatusFailed,
|
||||
TorrentName: selectedTorrent.Name,
|
||||
Message: fmt.Sprintf("Failed to send the stream to the media player, %v", err),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Listen to the playback status
|
||||
// Reset the current stream url when playback is stopped
|
||||
go func() {
|
||||
defer util.HandlePanicInModuleThen("debridstream/PlaybackSubscriber", func() {})
|
||||
defer func() {
|
||||
if s.playbackSubscriberCtxCancelFunc != nil {
|
||||
s.playbackSubscriberCtxCancelFunc()
|
||||
s.playbackSubscriberCtxCancelFunc = nil
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case <-playbackSubscriberCtx.Done():
|
||||
s.repository.wsEventManager.SendEvent(events.HideIndefiniteLoader, "debridstream")
|
||||
s.repository.playbackManager.UnsubscribeFromPlaybackStatus("debridstream")
|
||||
s.currentStreamUrl = ""
|
||||
case event := <-playbackSubscriber.EventCh:
|
||||
switch event.(type) {
|
||||
case playbackmanager.StreamStartedEvent:
|
||||
s.repository.wsEventManager.SendEvent(events.HideIndefiniteLoader, "debridstream")
|
||||
case playbackmanager.StreamStoppedEvent:
|
||||
go s.repository.playbackManager.UnsubscribeFromPlaybackStatus("debridstream")
|
||||
s.currentStreamUrl = ""
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
case PlaybackTypeExternalPlayer:
|
||||
// Send the external player link
|
||||
s.repository.wsEventManager.SendEventTo(opts.ClientId, events.ExternalPlayerOpenURL, struct {
|
||||
Url string `json:"url"`
|
||||
MediaId int `json:"mediaId"`
|
||||
EpisodeNumber int `json:"episodeNumber"`
|
||||
MediaTitle string `json:"mediaTitle"`
|
||||
}{
|
||||
Url: streamUrl,
|
||||
MediaId: opts.MediaId,
|
||||
EpisodeNumber: opts.EpisodeNumber,
|
||||
MediaTitle: media.GetPreferredTitle(),
|
||||
})
|
||||
|
||||
// Signal to the client that the torrent has started playing (remove loading status)
|
||||
// We can't know for sure
|
||||
s.repository.wsEventManager.SendEvent(events.DebridStreamState, StreamState{
|
||||
Status: StreamStatusReady,
|
||||
TorrentName: selectedTorrent.Name,
|
||||
Message: "External player link sent",
|
||||
})
|
||||
case PlaybackTypeNativePlayer:
|
||||
err := s.repository.directStreamManager.PlayDebridStream(ctx, directstream.PlayDebridStreamOptions{
|
||||
StreamUrl: streamUrl,
|
||||
MediaId: media.ID,
|
||||
EpisodeNumber: opts.EpisodeNumber,
|
||||
AnidbEpisode: opts.AniDBEpisode,
|
||||
Media: media,
|
||||
Torrent: selectedTorrent,
|
||||
FileId: fileId,
|
||||
UserAgent: opts.UserAgent,
|
||||
ClientId: opts.ClientId,
|
||||
AutoSelect: false,
|
||||
})
|
||||
if err != nil {
|
||||
s.repository.logger.Error().Err(err).Msg("directstream: Failed to prepare new stream")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
go func() {
|
||||
defer util.HandlePanicInModuleThen("debridstream/AddBatchHistory", func() {})
|
||||
|
||||
_ = db_bridge.InsertTorrentstreamHistory(s.repository.db, media.GetID(), selectedTorrent)
|
||||
}()
|
||||
}(ctx)
|
||||
|
||||
s.repository.wsEventManager.SendEvent(events.DebridStreamState, StreamState{
|
||||
Status: StreamStatusStarted,
|
||||
TorrentName: selectedTorrent.Name,
|
||||
Message: "Stream started",
|
||||
})
|
||||
s.repository.logger.Info().Msg("debridstream: Stream started")
|
||||
|
||||
if opts.PlaybackType == PlaybackTypeNoneAndAwait {
|
||||
s.repository.logger.Debug().Msg("debridstream: Waiting for stream to be ready")
|
||||
<-readyCh
|
||||
s.repository.wsEventManager.SendEvent(events.HideIndefiniteLoader, "debridstream")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *StreamManager) cancelStream(opts *CancelStreamOptions) {
|
||||
if s.downloadCtxCancelFunc != nil {
|
||||
s.downloadCtxCancelFunc()
|
||||
s.downloadCtxCancelFunc = nil
|
||||
}
|
||||
|
||||
s.repository.wsEventManager.SendEvent(events.ShowIndefiniteLoader, "debridstream")
|
||||
|
||||
s.currentStreamUrl = ""
|
||||
|
||||
if opts.RemoveTorrent && s.currentTorrentItemId != "" {
|
||||
// Remove the torrent from the debrid service
|
||||
provider, err := s.repository.GetProvider()
|
||||
if err != nil {
|
||||
s.repository.logger.Err(err).Msg("debridstream: Failed to remove torrent")
|
||||
return
|
||||
}
|
||||
|
||||
// Remove the torrent from the debrid service
|
||||
err = provider.DeleteTorrent(s.currentTorrentItemId)
|
||||
if err != nil {
|
||||
s.repository.logger.Err(err).Msg("debridstream: Failed to remove torrent")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
Reference in New Issue
Block a user