Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add express transcode server! #479

Closed
wants to merge 1 commit into from

Conversation

TheTacoScott
Copy link

@TheTacoScott TheTacoScott commented Jul 10, 2020

Wouldn't expect a merge, but the idea is cool and wanted to discuss.

One of the issues I ran into when doing something similar with python and flask (using ffmpeg to transcode video to chrome) was that once you seek to an offset, from the web browsers perspective THAT is the new "00:00:00.000" starting point.

ffmpeg doesn't send the timecodes with the actual video's timecodes in mind, it sends from the perspective of the start time (the -ss time).

The flask code here:

@app.route('/transcode/<path:filename>')
def transcode(filename):
    start = flask.request.args.get("start") or 0
    def generate():
        cmdline= list()
        cmdline.extend("nice -n19 ionice -c3".split(" "))
        cmdline.append("/usr/bin/ffmpeg")
        #cmdline.append("-noaccurate_seek")
        cmdline.extend("-hwaccel auto".split(" "))
        cmdline.append("-ss")
        cmdline.append(str(start));
        cmdline.extend("-i".split(" "))
        cmdline.append("/" + filename);
        cmdline.extend("-f mp4 -strict experimental -preset ultrafast -movflags frag_keyframe+empty_moov+faststart pipe:1".split(" "))
        print cmdline
        print " ".join(cmdline)
        FNULL = open(os.devnull, 'w')
        proc= subprocess.Popen( cmdline, stdout=subprocess.PIPE, stderr=FNULL)
        try:
            f= proc.stdout
            byte = f.read(1024*32)
            while byte:
                yield byte
                byte = f.read(1024*32)
        finally:
            proc.kill()
            FNULL.close()

    return flask.Response(response=generate(),status=200,mimetype='video/mp4',headers={'Access-Control-Allow-Origin': '*', "Content-Type":"video/mp4","Content-Disposition":"inline","Content-Transfer-Enconding":"binary"})

Very similar place we both got it.

On the web side of things it became important to make your own progress bar instead of using the built in html5 progress bar.

video tag (forgive the angular1):

<video preload="auto" id="mainvideo" ng-click="playPause($event)">
      <source type='video/mp4' src=''>
 </video>

One would then need to dynamically set the source for that video and "play it"
Simple enough, but once you seek it gets all wierd.

I did it with a dumb interval thing in angular1

$interval(function(){
		if ($scope.videoDom.readyState < 3) { return; }
		$scope.currentTime = parseFloat($scope.videoStart) + parseFloat($scope.videoDom.currentTime);
		$scope.videoPercent = parseFloat((($scope.currentTime * 100.00) / $scope.videoDuration).toFixed(1));
		$scope.videoVolume = $scope.videoDom.volume;

		if ($scope.videoDom.src.indexOf("transcode") < 0) {
			$scope.videoDom.src = "/transcode" + $scope.scene.linux_path + "?start="+$scope.videoStart;
		}
		
	},200);

One would have to bootstrap the total timecode for a video that is about to be transcoded I did that with a separate endpoint but really it could come in the headers or the vha2 file itself.
`
@app.route('/duration/path:filename')
def transcode_duration(filename):
cmdline= list()
cmdline.append("/usr/bin/ffmpeg")
cmdline.append("-i")
cmdline.append("/" + filename);
duration= -1
FNULL = open(os.devnull, 'w')
proc= subprocess.Popen( cmdline, stderr=subprocess.PIPE, stdout=FNULL )
try:
for line in iter(proc.stderr.readline,''):
line= line.rstrip()
#Duration: 00:00:45.13, start: 0.000000, bitrate: 302 kb/s
m = re.search('Duration: (..):(..):(..)...', line)
if m is not None: duration= int(m.group(1)) * 3600 + int(m.group(2)) * 60 + int(m.group(3)) + 1
finally:
proc.kill()

return flask.jsonify(duration=duration)

`

@cal2195
Copy link
Collaborator

cal2195 commented Jul 14, 2020

This branch is actually the precursor to the proper branch:
https://github.com/cal2195/Video-Hub-App/commits/transcoding-video

transcoding-video implements this better, along with a full video player UI and custom seek bar as you mentioned - as it's in app, it already knows the videos duration, so it doesn't need to ask for it:

cal2195@da445c9#diff-ede26585aa2866b9ae27054be48b7262R13

@whyboris whyboris changed the base branch from master to main July 26, 2020 20:08
@cal2195 cal2195 mentioned this pull request Nov 13, 2020
1 task
@whyboris
Copy link
Owner

Very related: #603 got merged into main -- we now have a dedicated server file already set up with an express server and a decent UI 👍

@whyboris
Copy link
Owner

whyboris commented Dec 18, 2020

I created my own PR as I'm working: #611 -- the code comes from @cal2195 🙇

@TheTacoScott -- let me know if it's OK to close this PR -- seems like we have virtually-identical code 🤝

@whyboris
Copy link
Owner

Closing in favor of #611 -- thank you @cal2195 and @TheTacoScott for your work 🙇

@whyboris whyboris closed this Dec 23, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants