|
|
|
@@ -68,7 +68,9 @@ func (rs sceneRoutes) Routes() chi.Router {
|
|
|
|
r.Get("/screenshot", rs.Screenshot)
|
|
|
|
r.Get("/screenshot", rs.Screenshot)
|
|
|
|
r.Get("/preview", rs.Preview)
|
|
|
|
r.Get("/preview", rs.Preview)
|
|
|
|
r.Get("/webp", rs.Webp)
|
|
|
|
r.Get("/webp", rs.Webp)
|
|
|
|
r.Get("/vtt/chapter", rs.ChapterVtt)
|
|
|
|
r.Get("/vtt/chapter", rs.VttChapter)
|
|
|
|
|
|
|
|
r.Get("/vtt/thumbs", rs.VttThumbs)
|
|
|
|
|
|
|
|
r.Get("/vtt/sprite", rs.VttSprite)
|
|
|
|
r.Get("/funscript", rs.Funscript)
|
|
|
|
r.Get("/funscript", rs.Funscript)
|
|
|
|
r.Get("/interactive_heatmap", rs.InteractiveHeatmap)
|
|
|
|
r.Get("/interactive_heatmap", rs.InteractiveHeatmap)
|
|
|
|
r.Get("/caption", rs.CaptionLang)
|
|
|
|
r.Get("/caption", rs.CaptionLang)
|
|
|
|
@@ -77,8 +79,8 @@ func (rs sceneRoutes) Routes() chi.Router {
|
|
|
|
r.Get("/scene_marker/{sceneMarkerId}/preview", rs.SceneMarkerPreview)
|
|
|
|
r.Get("/scene_marker/{sceneMarkerId}/preview", rs.SceneMarkerPreview)
|
|
|
|
r.Get("/scene_marker/{sceneMarkerId}/screenshot", rs.SceneMarkerScreenshot)
|
|
|
|
r.Get("/scene_marker/{sceneMarkerId}/screenshot", rs.SceneMarkerScreenshot)
|
|
|
|
})
|
|
|
|
})
|
|
|
|
r.With(rs.SceneCtx).Get("/{sceneId}_thumbs.vtt", rs.VttThumbs)
|
|
|
|
r.Get("/{sceneHash}_thumbs.vtt", rs.VttThumbs)
|
|
|
|
r.With(rs.SceneCtx).Get("/{sceneId}_sprite.jpg", rs.VttSprite)
|
|
|
|
r.Get("/{sceneHash}_sprite.jpg", rs.VttSprite)
|
|
|
|
|
|
|
|
|
|
|
|
return r
|
|
|
|
return r
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -87,11 +89,9 @@ func (rs sceneRoutes) Routes() chi.Router {
|
|
|
|
|
|
|
|
|
|
|
|
func (rs sceneRoutes) StreamDirect(w http.ResponseWriter, r *http.Request) {
|
|
|
|
func (rs sceneRoutes) StreamDirect(w http.ResponseWriter, r *http.Request) {
|
|
|
|
scene := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
scene := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
|
|
|
|
sceneHash := scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm())
|
|
|
|
|
|
|
|
|
|
|
|
fileNamingAlgo := config.GetInstance().GetVideoFileNamingAlgorithm()
|
|
|
|
filepath := manager.GetInstance().Paths.Scene.GetStreamPath(scene.Path, sceneHash)
|
|
|
|
hash := scene.GetHash(fileNamingAlgo)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
filepath := manager.GetInstance().Paths.Scene.GetStreamPath(scene.Path, hash)
|
|
|
|
|
|
|
|
streamRequestCtx := ffmpeg.NewStreamRequestContext(w, r)
|
|
|
|
streamRequestCtx := ffmpeg.NewStreamRequestContext(w, r)
|
|
|
|
|
|
|
|
|
|
|
|
// #2579 - hijacking and closing the connection here causes video playback to fail in Safari
|
|
|
|
// #2579 - hijacking and closing the connection here causes video playback to fail in Safari
|
|
|
|
@@ -229,8 +229,7 @@ func (rs sceneRoutes) streamSegment(w http.ResponseWriter, r *http.Request, stre
|
|
|
|
logger.Warnf("[transcode] error parsing query form: %v", err)
|
|
|
|
logger.Warnf("[transcode] error parsing query form: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fileNamingAlgo := config.GetInstance().GetVideoFileNamingAlgorithm()
|
|
|
|
sceneHash := scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm())
|
|
|
|
hash := scene.GetHash(fileNamingAlgo)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
segment := chi.URLParam(r, "segment")
|
|
|
|
segment := chi.URLParam(r, "segment")
|
|
|
|
resolution := r.Form.Get("resolution")
|
|
|
|
resolution := r.Form.Get("resolution")
|
|
|
|
@@ -239,7 +238,7 @@ func (rs sceneRoutes) streamSegment(w http.ResponseWriter, r *http.Request, stre
|
|
|
|
StreamType: streamType,
|
|
|
|
StreamType: streamType,
|
|
|
|
VideoFile: f,
|
|
|
|
VideoFile: f,
|
|
|
|
Resolution: resolution,
|
|
|
|
Resolution: resolution,
|
|
|
|
Hash: hash,
|
|
|
|
Hash: sceneHash,
|
|
|
|
Segment: segment,
|
|
|
|
Segment: segment,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -258,7 +257,8 @@ func (rs sceneRoutes) Screenshot(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
|
|
|
|
|
|
func (rs sceneRoutes) Preview(w http.ResponseWriter, r *http.Request) {
|
|
|
|
func (rs sceneRoutes) Preview(w http.ResponseWriter, r *http.Request) {
|
|
|
|
scene := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
scene := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
filepath := manager.GetInstance().Paths.Scene.GetVideoPreviewPath(scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm()))
|
|
|
|
sceneHash := scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm())
|
|
|
|
|
|
|
|
filepath := manager.GetInstance().Paths.Scene.GetVideoPreviewPath(sceneHash)
|
|
|
|
serveFileNoCache(w, r, filepath)
|
|
|
|
serveFileNoCache(w, r, filepath)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -272,7 +272,8 @@ func serveFileNoCache(w http.ResponseWriter, r *http.Request, filepath string) {
|
|
|
|
|
|
|
|
|
|
|
|
func (rs sceneRoutes) Webp(w http.ResponseWriter, r *http.Request) {
|
|
|
|
func (rs sceneRoutes) Webp(w http.ResponseWriter, r *http.Request) {
|
|
|
|
scene := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
scene := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
filepath := manager.GetInstance().Paths.Scene.GetWebpPreviewPath(scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm()))
|
|
|
|
sceneHash := scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm())
|
|
|
|
|
|
|
|
filepath := manager.GetInstance().Paths.Scene.GetWebpPreviewPath(sceneHash)
|
|
|
|
http.ServeFile(w, r, filepath)
|
|
|
|
http.ServeFile(w, r, filepath)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -308,7 +309,7 @@ func (rs sceneRoutes) getChapterVttTitle(ctx context.Context, marker *models.Sce
|
|
|
|
return &title, nil
|
|
|
|
return &title, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (rs sceneRoutes) ChapterVtt(w http.ResponseWriter, r *http.Request) {
|
|
|
|
func (rs sceneRoutes) VttChapter(w http.ResponseWriter, r *http.Request) {
|
|
|
|
scene := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
scene := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
var sceneMarkers []*models.SceneMarker
|
|
|
|
var sceneMarkers []*models.SceneMarker
|
|
|
|
readTxnErr := txn.WithReadTxn(r.Context(), rs.txnManager, func(ctx context.Context) error {
|
|
|
|
readTxnErr := txn.WithReadTxn(r.Context(), rs.txnManager, func(ctx context.Context) error {
|
|
|
|
@@ -350,6 +351,32 @@ func (rs sceneRoutes) ChapterVtt(w http.ResponseWriter, r *http.Request) {
|
|
|
|
_, _ = w.Write([]byte(vtt))
|
|
|
|
_, _ = w.Write([]byte(vtt))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (rs sceneRoutes) VttThumbs(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
|
|
scene, ok := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
|
|
|
|
var sceneHash string
|
|
|
|
|
|
|
|
if ok && scene != nil {
|
|
|
|
|
|
|
|
sceneHash = scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm())
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
sceneHash = chi.URLParam(r, "sceneHash")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
w.Header().Set("Content-Type", "text/vtt")
|
|
|
|
|
|
|
|
filepath := manager.GetInstance().Paths.Scene.GetSpriteVttFilePath(sceneHash)
|
|
|
|
|
|
|
|
http.ServeFile(w, r, filepath)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (rs sceneRoutes) VttSprite(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
|
|
scene, ok := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
|
|
|
|
var sceneHash string
|
|
|
|
|
|
|
|
if ok && scene != nil {
|
|
|
|
|
|
|
|
sceneHash = scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm())
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
sceneHash = chi.URLParam(r, "sceneHash")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
w.Header().Set("Content-Type", "image/jpeg")
|
|
|
|
|
|
|
|
filepath := manager.GetInstance().Paths.Scene.GetSpriteImageFilePath(sceneHash)
|
|
|
|
|
|
|
|
http.ServeFile(w, r, filepath)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (rs sceneRoutes) Funscript(w http.ResponseWriter, r *http.Request) {
|
|
|
|
func (rs sceneRoutes) Funscript(w http.ResponseWriter, r *http.Request) {
|
|
|
|
s := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
s := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
funscript := video.GetFunscriptPath(s.Path)
|
|
|
|
funscript := video.GetFunscriptPath(s.Path)
|
|
|
|
@@ -358,8 +385,9 @@ func (rs sceneRoutes) Funscript(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
|
|
|
|
|
|
func (rs sceneRoutes) InteractiveHeatmap(w http.ResponseWriter, r *http.Request) {
|
|
|
|
func (rs sceneRoutes) InteractiveHeatmap(w http.ResponseWriter, r *http.Request) {
|
|
|
|
scene := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
scene := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
|
|
|
|
sceneHash := scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm())
|
|
|
|
w.Header().Set("Content-Type", "image/png")
|
|
|
|
w.Header().Set("Content-Type", "image/png")
|
|
|
|
filepath := manager.GetInstance().Paths.Scene.GetInteractiveHeatmapPath(scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm()))
|
|
|
|
filepath := manager.GetInstance().Paths.Scene.GetInteractiveHeatmapPath(sceneHash)
|
|
|
|
http.ServeFile(w, r, filepath)
|
|
|
|
http.ServeFile(w, r, filepath)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -423,22 +451,9 @@ func (rs sceneRoutes) CaptionLang(w http.ResponseWriter, r *http.Request) {
|
|
|
|
rs.Caption(w, r, l, ext)
|
|
|
|
rs.Caption(w, r, l, ext)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (rs sceneRoutes) VttThumbs(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
|
|
scene := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
|
|
|
|
w.Header().Set("Content-Type", "text/vtt")
|
|
|
|
|
|
|
|
filepath := manager.GetInstance().Paths.Scene.GetSpriteVttFilePath(scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm()))
|
|
|
|
|
|
|
|
http.ServeFile(w, r, filepath)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (rs sceneRoutes) VttSprite(w http.ResponseWriter, r *http.Request) {
|
|
|
|
|
|
|
|
scene := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
|
|
|
|
w.Header().Set("Content-Type", "image/jpeg")
|
|
|
|
|
|
|
|
filepath := manager.GetInstance().Paths.Scene.GetSpriteImageFilePath(scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm()))
|
|
|
|
|
|
|
|
http.ServeFile(w, r, filepath)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (rs sceneRoutes) SceneMarkerStream(w http.ResponseWriter, r *http.Request) {
|
|
|
|
func (rs sceneRoutes) SceneMarkerStream(w http.ResponseWriter, r *http.Request) {
|
|
|
|
scene := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
scene := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
|
|
|
|
sceneHash := scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm())
|
|
|
|
sceneMarkerID, _ := strconv.Atoi(chi.URLParam(r, "sceneMarkerId"))
|
|
|
|
sceneMarkerID, _ := strconv.Atoi(chi.URLParam(r, "sceneMarkerId"))
|
|
|
|
var sceneMarker *models.SceneMarker
|
|
|
|
var sceneMarker *models.SceneMarker
|
|
|
|
readTxnErr := txn.WithReadTxn(r.Context(), rs.txnManager, func(ctx context.Context) error {
|
|
|
|
readTxnErr := txn.WithReadTxn(r.Context(), rs.txnManager, func(ctx context.Context) error {
|
|
|
|
@@ -460,12 +475,13 @@ func (rs sceneRoutes) SceneMarkerStream(w http.ResponseWriter, r *http.Request)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
filepath := manager.GetInstance().Paths.SceneMarkers.GetVideoPreviewPath(scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm()), int(sceneMarker.Seconds))
|
|
|
|
filepath := manager.GetInstance().Paths.SceneMarkers.GetVideoPreviewPath(sceneHash, int(sceneMarker.Seconds))
|
|
|
|
http.ServeFile(w, r, filepath)
|
|
|
|
http.ServeFile(w, r, filepath)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (rs sceneRoutes) SceneMarkerPreview(w http.ResponseWriter, r *http.Request) {
|
|
|
|
func (rs sceneRoutes) SceneMarkerPreview(w http.ResponseWriter, r *http.Request) {
|
|
|
|
scene := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
scene := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
|
|
|
|
sceneHash := scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm())
|
|
|
|
sceneMarkerID, _ := strconv.Atoi(chi.URLParam(r, "sceneMarkerId"))
|
|
|
|
sceneMarkerID, _ := strconv.Atoi(chi.URLParam(r, "sceneMarkerId"))
|
|
|
|
var sceneMarker *models.SceneMarker
|
|
|
|
var sceneMarker *models.SceneMarker
|
|
|
|
readTxnErr := txn.WithReadTxn(r.Context(), rs.txnManager, func(ctx context.Context) error {
|
|
|
|
readTxnErr := txn.WithReadTxn(r.Context(), rs.txnManager, func(ctx context.Context) error {
|
|
|
|
@@ -487,7 +503,7 @@ func (rs sceneRoutes) SceneMarkerPreview(w http.ResponseWriter, r *http.Request)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
filepath := manager.GetInstance().Paths.SceneMarkers.GetWebpPreviewPath(scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm()), int(sceneMarker.Seconds))
|
|
|
|
filepath := manager.GetInstance().Paths.SceneMarkers.GetWebpPreviewPath(sceneHash, int(sceneMarker.Seconds))
|
|
|
|
|
|
|
|
|
|
|
|
// If the image doesn't exist, send the placeholder
|
|
|
|
// If the image doesn't exist, send the placeholder
|
|
|
|
exists, _ := fsutil.FileExists(filepath)
|
|
|
|
exists, _ := fsutil.FileExists(filepath)
|
|
|
|
@@ -503,6 +519,7 @@ func (rs sceneRoutes) SceneMarkerPreview(w http.ResponseWriter, r *http.Request)
|
|
|
|
|
|
|
|
|
|
|
|
func (rs sceneRoutes) SceneMarkerScreenshot(w http.ResponseWriter, r *http.Request) {
|
|
|
|
func (rs sceneRoutes) SceneMarkerScreenshot(w http.ResponseWriter, r *http.Request) {
|
|
|
|
scene := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
scene := r.Context().Value(sceneKey).(*models.Scene)
|
|
|
|
|
|
|
|
sceneHash := scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm())
|
|
|
|
sceneMarkerID, _ := strconv.Atoi(chi.URLParam(r, "sceneMarkerId"))
|
|
|
|
sceneMarkerID, _ := strconv.Atoi(chi.URLParam(r, "sceneMarkerId"))
|
|
|
|
var sceneMarker *models.SceneMarker
|
|
|
|
var sceneMarker *models.SceneMarker
|
|
|
|
readTxnErr := txn.WithReadTxn(r.Context(), rs.txnManager, func(ctx context.Context) error {
|
|
|
|
readTxnErr := txn.WithReadTxn(r.Context(), rs.txnManager, func(ctx context.Context) error {
|
|
|
|
@@ -524,7 +541,7 @@ func (rs sceneRoutes) SceneMarkerScreenshot(w http.ResponseWriter, r *http.Reque
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
filepath := manager.GetInstance().Paths.SceneMarkers.GetScreenshotPath(scene.GetHash(config.GetInstance().GetVideoFileNamingAlgorithm()), int(sceneMarker.Seconds))
|
|
|
|
filepath := manager.GetInstance().Paths.SceneMarkers.GetScreenshotPath(sceneHash, int(sceneMarker.Seconds))
|
|
|
|
|
|
|
|
|
|
|
|
// If the image doesn't exist, send the placeholder
|
|
|
|
// If the image doesn't exist, send the placeholder
|
|
|
|
exists, _ := fsutil.FileExists(filepath)
|
|
|
|
exists, _ := fsutil.FileExists(filepath)
|
|
|
|
@@ -542,28 +559,16 @@ func (rs sceneRoutes) SceneMarkerScreenshot(w http.ResponseWriter, r *http.Reque
|
|
|
|
|
|
|
|
|
|
|
|
func (rs sceneRoutes) SceneCtx(next http.Handler) http.Handler {
|
|
|
|
func (rs sceneRoutes) SceneCtx(next http.Handler) http.Handler {
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
sceneIdentifierQueryParam := chi.URLParam(r, "sceneId")
|
|
|
|
sceneID, err := strconv.Atoi(chi.URLParam(r, "sceneId"))
|
|
|
|
sceneID, _ := strconv.Atoi(sceneIdentifierQueryParam)
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var scene *models.Scene
|
|
|
|
var scene *models.Scene
|
|
|
|
_ = txn.WithReadTxn(r.Context(), rs.txnManager, func(ctx context.Context) error {
|
|
|
|
_ = txn.WithReadTxn(r.Context(), rs.txnManager, func(ctx context.Context) error {
|
|
|
|
qb := rs.sceneFinder
|
|
|
|
qb := rs.sceneFinder
|
|
|
|
if sceneID == 0 {
|
|
|
|
scene, _ = qb.Find(ctx, sceneID)
|
|
|
|
var scenes []*models.Scene
|
|
|
|
|
|
|
|
// determine checksum/os by the length of the query param
|
|
|
|
|
|
|
|
if len(sceneIdentifierQueryParam) == 32 {
|
|
|
|
|
|
|
|
scenes, _ = qb.FindByChecksum(ctx, sceneIdentifierQueryParam)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
scenes, _ = qb.FindByOSHash(ctx, sceneIdentifierQueryParam)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if len(scenes) > 0 {
|
|
|
|
|
|
|
|
scene = scenes[0]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
scene, _ = qb.Find(ctx, sceneID)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if scene != nil {
|
|
|
|
if scene != nil {
|
|
|
|
if err := scene.LoadPrimaryFile(ctx, rs.fileFinder); err != nil {
|
|
|
|
if err := scene.LoadPrimaryFile(ctx, rs.fileFinder); err != nil {
|
|
|
|
|