Example #1
0
func (jc JobsController) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	urlComps := strings.Split(r.URL.Path, "/")
	identifier := ""
	if len(urlComps) > 0 {
		identifier = urlComps[0]
	}

	if identifier == "socket" {
		webSocketHandler.ServeHTTP(w, r)
		return
	}

	if r.Method == "GET" {
		j := jobstatus.Job{identifier}
		status, err := j.GetStatus()
		if err != nil {
			w.WriteHeader(500)
			fmt.Fprintln(w, "Error getting status:", err)
			return
		}
		bytes, err := json.Marshal(status)
		if err != nil {
			w.WriteHeader(500)
			fmt.Fprintln(w, "Error marshaling json:", err)
			return
		}

		w.Header().Add("Content-Type", "application/json")
		fmt.Fprintln(w, string(bytes))
	} else if r.Method == "POST" {
		var jobParams map[string]string
		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&jobParams)
		if err != nil {
			w.WriteHeader(500)
			fmt.Fprintln(w, "Error deocding json:", err)
			return
		}

		jid, err := workers.Enqueue("guide-upload-video-job", "UploadVideoJob", jobParams)
		if err != nil {
			w.WriteHeader(500)
			fmt.Fprintln(w, "Error dispatching job:", err)
			return
		}

		fmt.Fprintln(w, jid)
	}
}
Example #2
0
func WebSocketServer(ws *websocket.Conn) {
	for {
		var jobParams map[string]string
		if err := websocket.JSON.Receive(ws, &jobParams); err != nil {
			ws.Close()
			return
		}
		jid, err := workers.Enqueue("guide-upload-video-job", "UploadVideoJob", jobParams)
		if err != nil {
			log.Println("Error queueing job")
			ws.Close()
			return
		}

		j := jobstatus.Job{jid}
		status, err := j.GetStatus()
		if err != nil {
			log.Println("Error getting status:", err)
			ws.Close()
			return
		}

		uc, cc := status.UpdateChannel()

		for jobStatus := range uc {
			if err := websocket.JSON.Send(ws, jobStatus); err != nil {
				log.Println("Error sending updated status:", err)
				ws.Close()
				return
			} else if jobStatus.State == "done" {
				cc <- 1
				ws.Close()
				return
			} else {
				cc <- 0
			}
		}

	}
}
Example #3
0
func UploadVideoJob(msg *workers.Msg) {
	args := msg.Args()
	job := jobstatus.Job{msg.Jid()}
	status, _ := job.GetStatus()
	ytl, ytErr := args.Get("youtube_link").String()
	s3l, s3Err := args.Get("s3_link").String()
	cloudId, err := args.Get("s3id").String()
	if err != nil {
		log.Println("no s3id")
		job.AppendLog("no s3id")
		status.Read()
		status.State = "error"
		status.Save()
		return
	}

	logJobStatus := func(newLine string, isError bool) {
		log.Println(newLine)
		job.AppendLog(newLine)
		status.Read()
		if status.State == "queued" {
			status.State = "started"
		}
		status.Message = newLine
		status.Save()
	}
	dontLogAnything := func(newLine string, isError bool) {}

	updateJobProgress := func(complete int, total int) {
		status.Read()
		status.Complete = int64(complete)
		status.Total = int64(total)
		if complete == total {
			status.State = "done"
		} else {
			status.State = "started"
		}
		status.Save()
	}

	// First let's find the video we're using as input
	inputVideoName := msg.Jid() + ".mp4"
	log.Println("S3ERR:", s3Err, "YTERR:", ytErr)
	if s3Err == nil { // If they provided an s3 link, download it
		if err := downloadFromS3(s3l, inputVideoName, logJobStatus); err != nil {
			job.AppendLog("Error downloading from S3:")
			job.AppendLog(err.Error())
			status.Read()
			status.State = "error"
			status.Message = "Error downloading from S3"
			status.Save()
			log.Println("Error downloading from S3:", err)
		}
	} else if ytErr == nil { // If they provided a youtube link download it
		inputVideoName = "youtube.mp4"
		if err := downloadYoutubeVideo(ytl, "youtube", logJobStatus, updateJobProgress); err != nil {
			job.AppendLog("Error downloading youtube video:")
			job.AppendLog(err.Error())
			status.Read()
			status.State = "error"
			status.Message = "Error downloading from YouTube"
			status.Save()
			log.Println("Error downloading youtube video:", err)
		}
	} else { // If they provided nothing error out
		job.AppendLog("no input video to upload")
		status.Read()
		status.State = "error"
		status.Save()
		return
	}

	// Split the video into segments
	if err := splitVideoIntoSegments(inputVideoName, "segments/", logJobStatus); err != nil {
		job.AppendLog("Error segmenting video")
		job.AppendLog(err.Error())
		status.Read()
		status.State = "error"
		status.Message = "error segmenting video"
		status.Save()
		log.Println("Error segmenting video", err)
	}

	// generate some poster frames
	for i := 5; i < 10; i++ {
		posterName := fmt.Sprintf("segments/poster-%d.png", i)
		logMessage := fmt.Sprintf("Generating poster %d", i)
		if i == 5 {
			posterName = "segments/poster.png"
		}
		logJobStatus(logMessage, false)
		updateJobProgress(i-4, 6)
		if err := generatePoster(inputVideoName, i, posterName, dontLogAnything); err != nil {
			job.AppendLog("Error generating poster")
			job.AppendLog(err.Error())
			status.Read()
			status.State = "error"
			status.Message = "error generating poster"
			status.Save()
			log.Println("Error generating poster", err)
		}
	}

	// and upload everything to S3
	if err := uploadSegmentsToS3("segments/", cloudId, logJobStatus, updateJobProgress); err != nil {
		log.Println("Error uploading to S3:", err)
		job.AppendLog("Error uploading to S3")
		job.AppendLog(err.Error())
		status.Read()
		status.State = "error"
		status.Message = "Error uploading to s3"
		status.Save()
	}

	// Clean up
	os.Remove(scratchPath(inputVideoName))
	status.Read()
	status.State = "done"
	status.Message = "Uploaded video successfully"
	status.Save()
}