mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 21:46:11 +05:00
update
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/anacrolix/missinggo/httptoo"
|
||||
|
||||
sets "server/settings"
|
||||
"server/torr"
|
||||
"server/torr/state"
|
||||
@@ -23,7 +24,7 @@ import (
|
||||
func allPlayList(c *gin.Context) {
|
||||
torrs := torr.ListTorrent()
|
||||
|
||||
host := "http://" + c.Request.Host
|
||||
host := utils.GetScheme(c) + "://" + c.Request.Host
|
||||
list := "#EXTM3U\n"
|
||||
hash := ""
|
||||
// fn=file.m3u fix forkplayer bug with end .m3u in link
|
||||
@@ -60,7 +61,7 @@ func playList(c *gin.Context) {
|
||||
}
|
||||
}
|
||||
|
||||
host := "http://" + c.Request.Host
|
||||
host := utils.GetScheme(c) + "://" + c.Request.Host
|
||||
list := getM3uList(tor.Status(), host, fromlast)
|
||||
list = "#EXTM3U\n" + list
|
||||
|
||||
@@ -78,7 +79,6 @@ func sendM3U(c *gin.Context, name, hash string, m3u string) {
|
||||
}
|
||||
c.Header("Content-Disposition", `attachment; filename="`+name+`"`)
|
||||
http.ServeContent(c.Writer, c.Request, name, time.Now(), bytes.NewReader([]byte(m3u)))
|
||||
c.Status(200)
|
||||
}
|
||||
|
||||
func getM3uList(tor *state.TorrentStatus, host string, fromLast bool) string {
|
||||
@@ -98,10 +98,14 @@ func getM3uList(tor *state.TorrentStatus, host string, fromLast bool) string {
|
||||
fn = f.Path
|
||||
}
|
||||
m3u += "#EXTINF:0," + fn + "\n"
|
||||
subs := findSubs(tor.FileStats, f)
|
||||
if subs != nil {
|
||||
sname := filepath.Base(subs.Path)
|
||||
m3u += "#EXTVLCOPT:sub-file=" + host + "/stream/" + url.PathEscape(sname) + "?link=" + tor.Hash + "&index=" + fmt.Sprint(subs.Id) + "&play\n"
|
||||
fileNamesakes := findFileNamesakes(tor.FileStats, f) //find external media with same name (audio/subtiles tracks)
|
||||
if fileNamesakes != nil {
|
||||
m3u += "#EXTVLCOPT:input-slave=" //include VLC option for external media
|
||||
for _, namesake := range fileNamesakes { //include play-links to external media, with # splitter
|
||||
sname := filepath.Base(namesake.Path)
|
||||
m3u += host + "/stream/" + url.PathEscape(sname) + "?link=" + tor.Hash + "&index=" + fmt.Sprint(namesake.Id) + "&play#"
|
||||
}
|
||||
m3u += "\n"
|
||||
}
|
||||
name := filepath.Base(f.Path)
|
||||
m3u += host + "/stream/" + url.PathEscape(name) + "?link=" + tor.Hash + "&index=" + fmt.Sprint(f.Id) + "&play\n"
|
||||
@@ -111,19 +115,18 @@ func getM3uList(tor *state.TorrentStatus, host string, fromLast bool) string {
|
||||
return m3u
|
||||
}
|
||||
|
||||
func findSubs(files []*state.TorrentFileStat, file *state.TorrentFileStat) *state.TorrentFileStat {
|
||||
func findFileNamesakes(files []*state.TorrentFileStat, file *state.TorrentFileStat) []*state.TorrentFileStat {
|
||||
//find files with the same name in torrent
|
||||
name := filepath.Base(strings.TrimSuffix(file.Path, filepath.Ext(file.Path)))
|
||||
|
||||
var namesakes []*state.TorrentFileStat
|
||||
for _, f := range files {
|
||||
fname := strings.ToLower(filepath.Base(f.Path))
|
||||
if fname == strings.ToLower(name+".srt") {
|
||||
return f
|
||||
}
|
||||
if fname == strings.ToLower(name+".ass") {
|
||||
return f
|
||||
if strings.Contains(f.Path, name) { //external tracks always include name of videofile
|
||||
if f != file { //exclude itself
|
||||
namesakes = append(namesakes, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return namesakes
|
||||
}
|
||||
|
||||
func searchLastPlayed(tor *state.TorrentStatus) int {
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"server/torr"
|
||||
"server/torr/state"
|
||||
utils2 "server/utils"
|
||||
"server/web/api/utils"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -40,7 +41,7 @@ func stream(c *gin.Context) {
|
||||
data := ""
|
||||
notAuth := c.GetBool("not_auth")
|
||||
|
||||
if notAuth && play {
|
||||
if notAuth && (play || m3u) {
|
||||
streamNoAuth(c)
|
||||
return
|
||||
}
|
||||
@@ -119,7 +120,7 @@ func stream(c *gin.Context) {
|
||||
} else
|
||||
// return m3u if query
|
||||
if m3u {
|
||||
m3ulist := "#EXTM3U\n" + getM3uList(tor.Status(), "http://"+c.Request.Host, fromlast)
|
||||
m3ulist := "#EXTM3U\n" + getM3uList(tor.Status(), utils2.GetScheme(c)+"://"+c.Request.Host, fromlast)
|
||||
sendM3U(c, tor.Name()+".m3u", tor.Hash().HexString(), m3ulist)
|
||||
return
|
||||
} else
|
||||
@@ -134,6 +135,9 @@ func streamNoAuth(c *gin.Context) {
|
||||
link := c.Query("link")
|
||||
indexStr := c.Query("index")
|
||||
_, preload := c.GetQuery("preload")
|
||||
_, m3u := c.GetQuery("m3u")
|
||||
_, fromlast := c.GetQuery("fromlast")
|
||||
_, play := c.GetQuery("play")
|
||||
title := c.Query("title")
|
||||
poster := c.Query("poster")
|
||||
data := ""
|
||||
@@ -153,7 +157,8 @@ func streamNoAuth(c *gin.Context) {
|
||||
|
||||
tor := torr.GetTorrent(spec.InfoHash.HexString())
|
||||
if tor == nil {
|
||||
c.AbortWithStatus(http.StatusForbidden)
|
||||
c.Header("WWW-Authenticate", "Basic realm=Authorization Required")
|
||||
c.AbortWithStatus(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -184,7 +189,7 @@ func streamNoAuth(c *gin.Context) {
|
||||
index = ind
|
||||
}
|
||||
}
|
||||
if index == -1 { // if file index not set and play file exec
|
||||
if index == -1 && play { // if file index not set and play file exec
|
||||
c.AbortWithError(http.StatusBadRequest, errors.New("\"index\" is empty or wrong"))
|
||||
return
|
||||
}
|
||||
@@ -193,5 +198,18 @@ func streamNoAuth(c *gin.Context) {
|
||||
torr.Preload(tor, index)
|
||||
}
|
||||
|
||||
tor.Stream(index, c.Request, c.Writer)
|
||||
// return m3u if query
|
||||
if m3u {
|
||||
m3ulist := "#EXTM3U\n" + getM3uList(tor.Status(), utils2.GetScheme(c)+"://"+c.Request.Host, fromlast)
|
||||
sendM3U(c, tor.Name()+".m3u", tor.Hash().HexString(), m3ulist)
|
||||
return
|
||||
} else
|
||||
// return play if query
|
||||
if play {
|
||||
tor.Stream(index, c.Request, c.Writer)
|
||||
return
|
||||
}
|
||||
c.Header("WWW-Authenticate", "Basic realm=Authorization Required")
|
||||
c.AbortWithStatus(http.StatusUnauthorized)
|
||||
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ func ParseFile(file multipart.File) (*torrent.TorrentSpec, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mag := minfo.Magnet(info.Name, minfo.HashInfoBytes())
|
||||
// mag := minfo.Magnet(nil, &info)
|
||||
// mag := minfo.Magnet(info.Name, minfo.HashInfoBytes())
|
||||
mag := minfo.Magnet(nil, &info)
|
||||
return &torrent.TorrentSpec{
|
||||
InfoBytes: minfo.InfoBytes,
|
||||
Trackers: [][]string{mag.Trackers},
|
||||
@@ -74,17 +74,22 @@ func fromMagnet(link string) (*torrent.TorrentSpec, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
func fromHttp(url string) (*torrent.TorrentSpec, error) {
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
func fromHttp(link string) (*torrent.TorrentSpec, error) {
|
||||
req, err := http.NewRequest("GET", link, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client := new(http.Client)
|
||||
client.Timeout = time.Duration(time.Second * 30)
|
||||
client.Timeout = time.Duration(time.Second * 60)
|
||||
req.Header.Set("User-Agent", "DWL/1.1.1 (Torrent)")
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if er, ok := err.(*url.Error); ok {
|
||||
if strings.HasPrefix(er.URL, "magnet:") {
|
||||
return fromMagnet(er.URL)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -101,8 +106,8 @@ func fromHttp(url string) (*torrent.TorrentSpec, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mag := minfo.Magnet(info.Name, minfo.HashInfoBytes())
|
||||
// mag := minfo.Magnet(nil, &info)
|
||||
// mag := minfo.Magnet(info.Name, minfo.HashInfoBytes())
|
||||
mag := minfo.Magnet(nil, &info)
|
||||
|
||||
return &torrent.TorrentSpec{
|
||||
InfoBytes: minfo.InfoBytes,
|
||||
@@ -125,8 +130,8 @@ func fromFile(path string) (*torrent.TorrentSpec, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
mag := minfo.Magnet(info.Name, minfo.HashInfoBytes())
|
||||
// mag := minfo.Magnet(nil, &info)
|
||||
// mag := minfo.Magnet(info.Name, minfo.HashInfoBytes())
|
||||
mag := minfo.Magnet(nil, &info)
|
||||
return &torrent.TorrentSpec{
|
||||
InfoBytes: minfo.InfoBytes,
|
||||
Trackers: [][]string{mag.Trackers},
|
||||
|
||||
Reference in New Issue
Block a user