mirror of
				https://github.com/zoriya/Kyoo.git
				synced 2025-11-04 03:27:14 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			122 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			122 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package main
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
	"errors"
 | 
						|
	"fmt"
 | 
						|
	"net/http"
 | 
						|
 | 
						|
	_ "github.com/zoriya/kyoo/transcoder/docs"
 | 
						|
 | 
						|
	"github.com/golang-jwt/jwt/v5"
 | 
						|
	echoSwagger "github.com/swaggo/echo-swagger"
 | 
						|
	"github.com/zoriya/kyoo/transcoder/src"
 | 
						|
	"github.com/zoriya/kyoo/transcoder/src/api"
 | 
						|
	"github.com/zoriya/kyoo/transcoder/src/utils"
 | 
						|
 | 
						|
	"github.com/lestrrat-go/httprc/v3"
 | 
						|
	"github.com/lestrrat-go/jwx/v3/jwk"
 | 
						|
 | 
						|
	echojwt "github.com/labstack/echo-jwt/v4"
 | 
						|
	"github.com/labstack/echo/v4"
 | 
						|
	"github.com/labstack/echo/v4/middleware"
 | 
						|
)
 | 
						|
 | 
						|
func ErrorHandler(err error, c echo.Context) {
 | 
						|
	code := http.StatusInternalServerError
 | 
						|
	var message string
 | 
						|
	if he, ok := err.(*echo.HTTPError); ok {
 | 
						|
		code = he.Code
 | 
						|
		message = fmt.Sprint(he.Message)
 | 
						|
	} else {
 | 
						|
		c.Logger().Error(err)
 | 
						|
		message = "Internal server error"
 | 
						|
	}
 | 
						|
	c.JSON(code, struct {
 | 
						|
		Errors []string `json:"errors"`
 | 
						|
	}{Errors: []string{message}})
 | 
						|
}
 | 
						|
 | 
						|
// @title gocoder - Kyoo's transcoder
 | 
						|
// @version 1.0
 | 
						|
// @description Real time transcoder.
 | 
						|
 | 
						|
// @contact.name Repository
 | 
						|
// @contact.url https://github.com/zoriya/kyoo
 | 
						|
 | 
						|
// @license.name  GPL-3.0
 | 
						|
// @license.url https://www.gnu.org/licenses/gpl-3.0.en.html
 | 
						|
 | 
						|
// @host kyoo.zoriya.dev
 | 
						|
// @BasePath /video
 | 
						|
 | 
						|
// @securityDefinitions.apiKey Token
 | 
						|
// @in header
 | 
						|
// @name Authorization
 | 
						|
 | 
						|
// @securityDefinitions.apiKey Jwt
 | 
						|
// @in header
 | 
						|
// @name Authorization
 | 
						|
func main() {
 | 
						|
	e := echo.New()
 | 
						|
	e.Use(middleware.Logger())
 | 
						|
	e.GET("/video/swagger/*", echoSwagger.WrapHandler)
 | 
						|
	e.HTTPErrorHandler = ErrorHandler
 | 
						|
 | 
						|
	metadata, err := src.NewMetadataService()
 | 
						|
	if err != nil {
 | 
						|
		e.Logger.Fatal("failed to create metadata service: ", err)
 | 
						|
		return
 | 
						|
	}
 | 
						|
	defer utils.CleanupWithErr(&err, metadata.Close, "failed to close metadata service")
 | 
						|
 | 
						|
	transcoder, err := src.NewTranscoder(metadata)
 | 
						|
	if err != nil {
 | 
						|
		e.Logger.Fatal("failed to create transcoder: ", err)
 | 
						|
		return
 | 
						|
	}
 | 
						|
 | 
						|
	g := e.Group("/video")
 | 
						|
 | 
						|
	if src.Settings.JwksUrl != "" {
 | 
						|
		ctx, cancel := context.WithCancel(context.Background())
 | 
						|
		defer cancel()
 | 
						|
 | 
						|
		jwks, err := jwk.NewCache(ctx, httprc.NewClient())
 | 
						|
		if err != nil {
 | 
						|
			e.Logger.Fatal("failed to create jwk cache: ", err)
 | 
						|
			return
 | 
						|
		}
 | 
						|
		jwks.Register(ctx, src.Settings.JwksUrl)
 | 
						|
		g.Use(echojwt.WithConfig(echojwt.Config{
 | 
						|
			KeyFunc: func(token *jwt.Token) (any, error) {
 | 
						|
				keys, err := jwks.CachedSet(src.Settings.JwksUrl)
 | 
						|
				if err != nil {
 | 
						|
					return nil, err
 | 
						|
				}
 | 
						|
				kid, ok := token.Header["kid"].(string)
 | 
						|
				if !ok {
 | 
						|
					return nil, errors.New("missing kid in jwt")
 | 
						|
				}
 | 
						|
				key, found := keys.LookupKeyID(kid)
 | 
						|
				if !found {
 | 
						|
					return nil, fmt.Errorf("unable to find key %q", kid)
 | 
						|
				}
 | 
						|
 | 
						|
				var pubkey interface{}
 | 
						|
				if err := jwk.Export(key, &pubkey); err != nil {
 | 
						|
					return nil, fmt.Errorf("Unable to get the public key. Error: %s", err.Error())
 | 
						|
				}
 | 
						|
 | 
						|
				return pubkey, nil
 | 
						|
			},
 | 
						|
		}))
 | 
						|
	}
 | 
						|
 | 
						|
	api.RegisterStreamHandlers(g, transcoder)
 | 
						|
	api.RegisterMetadataHandlers(g, metadata)
 | 
						|
	api.RegisterPProfHandlers(e)
 | 
						|
 | 
						|
	e.Logger.Fatal(e.Start(":7666"))
 | 
						|
}
 |