init
This commit is contained in:
		
							
								
								
									
										81
									
								
								handler/engine.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										81
									
								
								handler/engine.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,81 @@
 | 
			
		||||
package handler
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/anacrolix/torrent"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
	"os"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Engine struct {
 | 
			
		||||
	client      *torrent.Client
 | 
			
		||||
	files       map[string]*MovieTorrent
 | 
			
		||||
	storagePath string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewEngine(storagePath string) (*Engine, error) {
 | 
			
		||||
	logrus.Info("Creating Streaming engine")
 | 
			
		||||
	if storagePath == "" {
 | 
			
		||||
		storagePath = os.TempDir()
 | 
			
		||||
		logrus.Debug("Storage path undefined. Using default temp directory")
 | 
			
		||||
	}
 | 
			
		||||
	logrus.Debugf("Storage Path: %s", storagePath)
 | 
			
		||||
	conf := torrent.NewDefaultClientConfig()
 | 
			
		||||
	conf.DataDir = storagePath
 | 
			
		||||
	c, err := torrent.NewClient(conf)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	return &Engine{c, map[string]*MovieTorrent{}, storagePath}, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *Engine) Close() {
 | 
			
		||||
	e.client.Close()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *Engine) Get(fileName string) (*MovieTorrent, error) {
 | 
			
		||||
	logrus.Infof("Requesting torrent: %s", fileName)
 | 
			
		||||
	if mt, ok := e.files[fileName]; ok {
 | 
			
		||||
		return mt, nil
 | 
			
		||||
	}
 | 
			
		||||
	return nil, fmt.Errorf("not found: %s", fileName)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (e *Engine) Prepare(magnet string) error {
 | 
			
		||||
	logrus.Debugf("preparing magnet: %s", magnet)
 | 
			
		||||
	t, err := e.client.AddMagnet(magnet)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	<-t.GotInfo()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
func (e *Engine) Download(magnet string) (*MovieTorrent, error) {
 | 
			
		||||
	logrus.Debugf("downloading magnet: %s", magnet)
 | 
			
		||||
	t, err := e.client.AddMagnet(magnet)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	<-t.GotInfo()
 | 
			
		||||
	file := getLargestFile(t)
 | 
			
		||||
	file.Download()
 | 
			
		||||
	mt := newMovieTorrent(file, t)
 | 
			
		||||
	mt.engine = e
 | 
			
		||||
	e.files[mt.FileName] = mt
 | 
			
		||||
	logrus.Infof("Downloading: %s", mt.FileName)
 | 
			
		||||
	return mt, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getLargestFile(t *torrent.Torrent) *torrent.File {
 | 
			
		||||
	var target *torrent.File
 | 
			
		||||
	var maxSize int64
 | 
			
		||||
 | 
			
		||||
	for _, file := range t.Files() {
 | 
			
		||||
		if maxSize < file.Length() {
 | 
			
		||||
			maxSize = file.Length()
 | 
			
		||||
			target = file
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return target
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										260
									
								
								handler/handler.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										260
									
								
								handler/handler.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,260 @@
 | 
			
		||||
package handler
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"git.adphi.net/Adphi/ytsflix/templates"
 | 
			
		||||
	"git.adphi.net/Adphi/ytsflix/ytsclient"
 | 
			
		||||
	"github.com/dustin/go-humanize"
 | 
			
		||||
	"github.com/gorilla/mux"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
	"gopkg.in/h2non/filetype.v1"
 | 
			
		||||
	"io"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	_ io.Reader = (*os.File)(nil)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type Handler struct {
 | 
			
		||||
	engine      *Engine
 | 
			
		||||
	clients     map[string]int
 | 
			
		||||
	yts         *ytsclient.Client
 | 
			
		||||
	mutex       sync.Mutex
 | 
			
		||||
	storagePath string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type HomeData struct {
 | 
			
		||||
	Categories map[string]map[string]Movie
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Movie struct {
 | 
			
		||||
	Title    string
 | 
			
		||||
	Year     int
 | 
			
		||||
	Cover    string
 | 
			
		||||
	Link     string
 | 
			
		||||
	Synopsis string
 | 
			
		||||
	Genre    []string
 | 
			
		||||
	Youtube  string
 | 
			
		||||
	Casting  []Cast
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Cast struct {
 | 
			
		||||
	Name  string
 | 
			
		||||
	Image string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type MovieData struct {
 | 
			
		||||
	Title     string
 | 
			
		||||
	Link      string
 | 
			
		||||
	Subtitles map[string]string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func NewHandler(storagePath string) (*Handler, error) {
 | 
			
		||||
	h := Handler{storagePath: storagePath}
 | 
			
		||||
	var err error
 | 
			
		||||
	h.engine, err = NewEngine(storagePath)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
	}
 | 
			
		||||
	h.yts = ytsclient.NewClient("https://yts.am/api/v2")
 | 
			
		||||
	h.clients = map[string]int{}
 | 
			
		||||
	return &h, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *Handler) Close() {
 | 
			
		||||
	h.engine.Close()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *Handler) Home(writer http.ResponseWriter, request *http.Request) {
 | 
			
		||||
	hd := HomeData{Categories: map[string]map[string]Movie{}}
 | 
			
		||||
	var mu sync.Mutex
 | 
			
		||||
	var wg sync.WaitGroup
 | 
			
		||||
	wg.Add(len(ytsclient.Genres))
 | 
			
		||||
	for _, g := range ytsclient.Genres {
 | 
			
		||||
		go func(genre ytsclient.Genre) {
 | 
			
		||||
			defer wg.Done()
 | 
			
		||||
			res, err := h.yts.List(&ytsclient.ListParams{
 | 
			
		||||
				Genre:   genre,
 | 
			
		||||
				Limit:   50,
 | 
			
		||||
				SortBy:  ytsclient.Year,
 | 
			
		||||
				OrderBy: ytsclient.Desc,
 | 
			
		||||
				Quality: ytsclient.Quality1080p,
 | 
			
		||||
			})
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				sendError(writer, err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			ms := map[string]Movie{}
 | 
			
		||||
			for _, m := range res {
 | 
			
		||||
				ms[m.Title] = Movie{
 | 
			
		||||
					Link:  fmt.Sprintf("/movie/%d", m.ID),
 | 
			
		||||
					Cover: m.MediumCoverImage,
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
			if len(ms) >= 10 {
 | 
			
		||||
				mu.Lock()
 | 
			
		||||
				hd.Categories[string(genre)] = ms
 | 
			
		||||
				mu.Unlock()
 | 
			
		||||
			}
 | 
			
		||||
		}(g)
 | 
			
		||||
	}
 | 
			
		||||
	wg.Wait()
 | 
			
		||||
	t := templates.HomeTemplate()
 | 
			
		||||
	writer.Header().Set("Content-Type", "text/html; charset=utf-8")
 | 
			
		||||
	writer.WriteHeader(200)
 | 
			
		||||
	t.Execute(writer, hd)
 | 
			
		||||
 | 
			
		||||
	//fmt.Fprint(writer, html)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *Handler) Movie(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
	id := mux.Vars(r)["id"]
 | 
			
		||||
	m, err := h.yts.Get(id, nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		sendError(w, err)
 | 
			
		||||
	}
 | 
			
		||||
	go func() { h.engine.Prepare(getMagnet(m)) }()
 | 
			
		||||
	t := templates.MovieTemplate()
 | 
			
		||||
	var cast []Cast
 | 
			
		||||
	for _, c := range m.Cast {
 | 
			
		||||
		cast = append(cast, Cast{Name: c.Name, Image: c.URLSmallImage})
 | 
			
		||||
	}
 | 
			
		||||
	md := Movie{
 | 
			
		||||
		Title:    m.Title,
 | 
			
		||||
		Year:     m.Year,
 | 
			
		||||
		Genre:    m.Genres,
 | 
			
		||||
		Cover:    m.MediumCoverImage,
 | 
			
		||||
		Link:     fmt.Sprintf("/torrent/%d", m.ID),
 | 
			
		||||
		Synopsis: m.DescriptionFull,
 | 
			
		||||
		Youtube:  fmt.Sprintf("https://www.youtube.com/embed/%s", m.YtTrailerCode),
 | 
			
		||||
		Casting:  cast,
 | 
			
		||||
	}
 | 
			
		||||
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
 | 
			
		||||
	t.Execute(w, md)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *Handler) Search(writer http.ResponseWriter, request *http.Request) {
 | 
			
		||||
	vars := mux.Vars(request)
 | 
			
		||||
	s := vars["search"]
 | 
			
		||||
	ms, err := h.yts.Search(s, &ytsclient.ListParams{Quality: ytsclient.Quality1080p})
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		sendError(writer, err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	html := "<ul>"
 | 
			
		||||
	for _, m := range ms {
 | 
			
		||||
		html += fmt.Sprintf("<li><a href=\"/movie/%d\">%s</a></li>", m.ID, m.Title)
 | 
			
		||||
	}
 | 
			
		||||
	html += "</ul>"
 | 
			
		||||
	writer.Header().Set("Content-Type", "text/html; charset=utf-8")
 | 
			
		||||
	writer.WriteHeader(200)
 | 
			
		||||
	fmt.Fprint(writer, html)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *Handler) Torrents(writer http.ResponseWriter, request *http.Request) {
 | 
			
		||||
	id := mux.Vars(request)["id"]
 | 
			
		||||
	m, err := h.yts.Get(id, nil)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		sendError(writer, err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	magnet := getMagnet(m)
 | 
			
		||||
	mt, err := h.engine.Download(magnet)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		sendError(writer, err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if err := mt.DownloadSubtitles(m.ImdbCode); err != nil {
 | 
			
		||||
		logrus.Error(err)
 | 
			
		||||
	}
 | 
			
		||||
	cp := mt.Progress()
 | 
			
		||||
	go func() {
 | 
			
		||||
		for p := range cp {
 | 
			
		||||
			hSize := humanize.Bytes(uint64(p.Size))
 | 
			
		||||
			downloadSpeed := humanize.Bytes(p.DownloadSpeed) + "/s"
 | 
			
		||||
			complete := humanize.Bytes(p.Downloaded)
 | 
			
		||||
			logrus.Debugf("%s: Progress: %s / %s  %s", mt.FileName, complete, hSize, downloadSpeed)
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	link := fmt.Sprintf("/watch/%s", mt.FileName)
 | 
			
		||||
 | 
			
		||||
	ss := map[string]string{}
 | 
			
		||||
	for s, v := range mt.Subtitles {
 | 
			
		||||
		ss[strings.Replace(s, ".vtt", "", -1)] = fmt.Sprintf("/subs/%s", v)
 | 
			
		||||
	}
 | 
			
		||||
	md := MovieData{Title: mt.FileName, Link: link, Subtitles: ss}
 | 
			
		||||
 | 
			
		||||
	writer.Header().Set("Content-Type", "text/html; charset=utf-8")
 | 
			
		||||
	writer.WriteHeader(200)
 | 
			
		||||
	t := templates.WatchTemplate()
 | 
			
		||||
	t.Execute(writer, md)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *Handler) Serve(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
	vars := mux.Vars(r)
 | 
			
		||||
	var mt *MovieTorrent
 | 
			
		||||
	var err error
 | 
			
		||||
	movie := vars["movie"]
 | 
			
		||||
	h.mutex.Lock()
 | 
			
		||||
	h.clients[movie]++
 | 
			
		||||
	h.mutex.Unlock()
 | 
			
		||||
	if mt, err = h.engine.Get(movie); err != nil {
 | 
			
		||||
		http.Error(w, "file not found", http.StatusBadRequest)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	reader := mt.NewReader()
 | 
			
		||||
	defer reader.Close()
 | 
			
		||||
	defer func() {
 | 
			
		||||
		h.mutex.Lock()
 | 
			
		||||
		h.clients[movie]--
 | 
			
		||||
		h.mutex.Unlock()
 | 
			
		||||
		time.Sleep(5 * time.Second)
 | 
			
		||||
		if h.clients[movie] == 0 {
 | 
			
		||||
			logrus.Infof("The client closed the connection. Cleaning up: %s.", movie)
 | 
			
		||||
			mt.Cancel()
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	w.Header().Set("Connection", "Keep-Alive")
 | 
			
		||||
	w.Header().Set("Content-Type", mt.MIME)
 | 
			
		||||
	http.ServeContent(w, r, mt.FileName, time.Now(), reader)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *Handler) Sub(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
	vars := mux.Vars(r)
 | 
			
		||||
	m := vars["movie"]
 | 
			
		||||
	s := vars["sub"]
 | 
			
		||||
	logrus.Debugf("requesting subs: movie: %s, sub: %s", vars["movie"], vars["sub"])
 | 
			
		||||
	f, err := os.Open(fmt.Sprintf("%s/%s/%s", h.storagePath, m, s))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		sendError(w, err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	mime := filetype.GetType(".vtt").MIME.Value
 | 
			
		||||
	w.Header().Add("Context-Type", mime)
 | 
			
		||||
	http.ServeContent(w, r, vars["sub"], time.Now(), f)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func sendError(writer http.ResponseWriter, err error) {
 | 
			
		||||
	logrus.Error(err)
 | 
			
		||||
	http.Error(writer, err.Error(), http.StatusInternalServerError)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getMagnet(m ytsclient.Movie) string {
 | 
			
		||||
	var to *ytsclient.Torrent
 | 
			
		||||
	for _, t := range m.Torrents {
 | 
			
		||||
		if t.Quality == string(ytsclient.Quality1080p) {
 | 
			
		||||
			to = &t
 | 
			
		||||
			break
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	if to == nil {
 | 
			
		||||
		to = &m.Torrents[0]
 | 
			
		||||
	}
 | 
			
		||||
	magnet, _ := m.Magnet(*to)
 | 
			
		||||
	return magnet
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										145
									
								
								handler/movietorrent.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								handler/movietorrent.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,145 @@
 | 
			
		||||
package handler
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"github.com/anacrolix/torrent"
 | 
			
		||||
	"github.com/asticode/go-astisub"
 | 
			
		||||
	"github.com/odwrtw/yifysubs"
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
	"gopkg.in/h2non/filetype.v1"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
	"time"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type MovieTorrent struct {
 | 
			
		||||
	FileName  string
 | 
			
		||||
	MIME      string
 | 
			
		||||
	Subtitles map[string]string
 | 
			
		||||
	torrent   *torrent.Torrent
 | 
			
		||||
	file      *torrent.File
 | 
			
		||||
	engine    *Engine
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newMovieTorrent(file *torrent.File, t *torrent.Torrent) *MovieTorrent {
 | 
			
		||||
	fileName := filepath.Base(file.Path())
 | 
			
		||||
	ext := strings.SplitAfter(path.Ext(fileName), ".")[1]
 | 
			
		||||
	MIME := filetype.GetType(ext).MIME.Value
 | 
			
		||||
	return &MovieTorrent{
 | 
			
		||||
		torrent:  t,
 | 
			
		||||
		file:     file,
 | 
			
		||||
		FileName: fileName,
 | 
			
		||||
		MIME:     MIME,
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type Progress struct {
 | 
			
		||||
	Downloaded    uint64
 | 
			
		||||
	Size          uint64
 | 
			
		||||
	DownloadSpeed uint64
 | 
			
		||||
	Percentage    int
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MovieTorrent) NewReader() torrent.Reader {
 | 
			
		||||
	reader := m.file.NewReader()
 | 
			
		||||
	reader.SetReadahead(m.file.Length() / 100)
 | 
			
		||||
	reader.SetResponsive()
 | 
			
		||||
	return reader
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MovieTorrent) Progress() chan Progress {
 | 
			
		||||
	pc := make(chan Progress)
 | 
			
		||||
	var p int64 = 0
 | 
			
		||||
	size := m.torrent.Info().TotalLength()
 | 
			
		||||
	c := m.torrent.Closed()
 | 
			
		||||
	go func() {
 | 
			
		||||
		defer close(pc)
 | 
			
		||||
		for {
 | 
			
		||||
			select {
 | 
			
		||||
			case <-c:
 | 
			
		||||
				logrus.Debugf("%s stopped", m.FileName)
 | 
			
		||||
				return
 | 
			
		||||
			default:
 | 
			
		||||
				if p >= size {
 | 
			
		||||
					logrus.Debugf("%s completed", m.FileName)
 | 
			
		||||
					return
 | 
			
		||||
				}
 | 
			
		||||
				currentProgress := m.torrent.BytesCompleted()
 | 
			
		||||
				percent := int(float64(currentProgress) / float64(size) * 100)
 | 
			
		||||
				pc <- Progress{
 | 
			
		||||
					Downloaded:    uint64(currentProgress),
 | 
			
		||||
					Size:          uint64(size),
 | 
			
		||||
					Percentage:    percent,
 | 
			
		||||
					DownloadSpeed: uint64(currentProgress - p),
 | 
			
		||||
				}
 | 
			
		||||
				p = currentProgress
 | 
			
		||||
				time.Sleep(time.Second)
 | 
			
		||||
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}()
 | 
			
		||||
	return pc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MovieTorrent) Cancel() {
 | 
			
		||||
	logrus.Infof("Stopping torrent: %s", m.FileName)
 | 
			
		||||
	m.torrent.Drop()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *MovieTorrent) DownloadSubtitles(imdbID string) error {
 | 
			
		||||
	logrus.Infof("Getting subtitles for: %s", m.FileName)
 | 
			
		||||
	//Create a client
 | 
			
		||||
	client := yifysubs.New("http://yifysubtitles.com")
 | 
			
		||||
 | 
			
		||||
	//Search subtitles
 | 
			
		||||
	subtitles, err := client.Search(imdbID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	m.Subtitles = map[string]string{}
 | 
			
		||||
	basePath := filepath.Join(m.engine.storagePath, filepath.Dir(m.file.Path()))
 | 
			
		||||
	logrus.Debugf("Subtitles base path: %s", basePath)
 | 
			
		||||
	if _, err := os.Stat(basePath); os.IsNotExist(err) {
 | 
			
		||||
		os.Mkdir(basePath, os.ModePerm)
 | 
			
		||||
	}
 | 
			
		||||
	var wg sync.WaitGroup
 | 
			
		||||
	wg.Add(len(subtitles))
 | 
			
		||||
	mx := sync.RWMutex{}
 | 
			
		||||
	for _, subtitle := range subtitles {
 | 
			
		||||
		go func(sub *yifysubs.Subtitle) {
 | 
			
		||||
			defer wg.Done()
 | 
			
		||||
			name := fmt.Sprintf("%s.vtt", sub.Lang)
 | 
			
		||||
			ref := filepath.Join(filepath.Dir(m.file.Path()), name)
 | 
			
		||||
			p := filepath.Join(basePath, name)
 | 
			
		||||
			if _, err := os.Stat(p); err == nil {
 | 
			
		||||
				mx.Lock()
 | 
			
		||||
				m.Subtitles[name] = ref
 | 
			
		||||
				mx.Unlock()
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			file, err := os.Create(p)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				logrus.Error(err)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			defer file.Close()
 | 
			
		||||
			defer sub.Close()
 | 
			
		||||
			s, _ := astisub.ReadFromSRT(sub)
 | 
			
		||||
 | 
			
		||||
			if err := s.WriteToWebVTT(file); err != nil {
 | 
			
		||||
				logrus.Debugf("error subtitle: %v", err)
 | 
			
		||||
				os.Remove(p)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
			mx.Lock()
 | 
			
		||||
			m.Subtitles[name] = ref
 | 
			
		||||
			mx.Unlock()
 | 
			
		||||
 | 
			
		||||
		}(subtitle)
 | 
			
		||||
	}
 | 
			
		||||
	wg.Wait()
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user