Using VLC to transcode video to H.264/AAC

Third-party modifications and add-ons, Apps and Clients

Moderator: moderators

Using VLC to transcode video to H.264/AAC

Postby diego_dambra » Sat Feb 05, 2011 1:39 pm

I've created a simple script that uses VLC to transcode video to H.264/AAC for better quality at lower CPU and bandwidth usage.

It can be considered as a drop-in replacement for the current FFMpeg solution. At 700Kbps it will deliver crisp clear video transcoding e.g. 720p .mkv video stream using a low end Intel Atom processor. Higher resolution will result in video stutter unless you've the CPU power available.

I've only tested the script on Linux (and some changes are needed before it would work in Windows). And it requires VLC is installed on your system.

To use it download and place the vlc.pl script in the transcoding folder (remember execute permission) and replace the transcoding ffmpeg step with:
Code: Select all
vlc.pl -i '%s' --canvas %wx%h --video-bit %b --username NONROOTUSER

The NONROOTUSER is needed since VLC will not run as root (you can skip the --username option, if Subsonic isn't running as root).
diego_dambra
 
Posts: 5
Joined: Tue Jan 25, 2011 8:12 pm

Re: Using VLC to transcode video to H.264/AAC

Postby calvintml » Thu Feb 24, 2011 5:19 am

have you by any chance updated your vlc.pl script to support skipping to different times in a video (as is currently possible with ffmpeg)?
calvintml
 
Posts: 6
Joined: Thu Feb 24, 2011 5:17 am

gpu accelerated transcoding

Postby calvintml » Sat Feb 26, 2011 1:14 am

Is it possible to use gpu accelerated transcoding software like "Badaboom" for nvidia cards and "ATI avivo" for ati cards to save cpu cycles?
calvintml
 
Posts: 6
Joined: Thu Feb 24, 2011 5:17 am

Postby sekhu » Mon Mar 07, 2011 12:06 am

what would be the windows equivalent command? I'm looking for a better way to stream 720p video. The result at themoment is very choppy :(

thank you
sekhu
 
Posts: 20
Joined: Fri Mar 04, 2011 10:47 pm

Postby privatesam » Tue Mar 08, 2011 11:38 am

I'm very interested in what VLC can do - is there anyone who knows the windows commands? Would love to help with this.

As far as the GPU specific encoders I know that Nvidia's Badaboom is a paid for software so I doubt Subsonic will offer support in the slightest - still there may be some peeps around here who know how to use it for this.
privatesam
 
Posts: 19
Joined: Fri Feb 26, 2010 10:09 am

Postby privatesam » Tue Mar 08, 2011 11:43 am

As for VLC I stuff here: http://www.videolan.org/doc/vlc-user-guide/en/ch04.html with specific mention of transcoding on the fly here: Architecture and syntax

the stream output has a powerful architecture that uses modules. Each module has capabilities, and you can chain the modules to enhance the possibilities.

Here is the list of the modules currently available:

standard "sends" the stream via an access output module: for example, UDP, file, HTTP, ... You will probably want to use this module at the end of your chains.

transcode allows you to transcode the audio and the video of the input stream "on the fly" (if your computer is powerful enough).

duplicate allows you to create a second chain, where the stream will be handled in an independant way.

display allows you to display the input stream, as VLC would normally do. Used with the duplicate module, this allows you to view the stream as you send it.

rtp streams over RTP (one UDP port for each elementary stream).

es allows you to make separate Elementary Streams (ES) out of an input stream.

Each of these modules may take options. Here is the syntax that you must use:

% vlc input_stream --sout '#module1{option1=...,option2=...}:module2{option1=...,option2=...}:...'
You may also use the following syntax :

% vlc input_stream --sout-module1-option1=... --sout-module1-option2=... --sout-module2-option1=... --sout-module2-option2=... ...
For example, to transcode a stream and send it, use:

% vlc input_stream --sout '#transcode{options}:standard{options}'
privatesam
 
Posts: 19
Joined: Fri Feb 26, 2010 10:09 am

Postby privatesam » Thu Mar 17, 2011 1:46 pm

To those asking , user Castius, has got some VLC transcoding working in windows. I've yet to try it but it seems interesting and worth a go - see the last post on this thread: http://forum.subsonic.org/forum/viewtop ... c&start=15
privatesam
 
Posts: 19
Joined: Fri Feb 26, 2010 10:09 am

Postby gordon12393 » Mon Mar 28, 2011 5:27 pm

diego_dambra,

I added this script to my ubuntu system with subsonic. When I try to play a video I get an error stating "cannot find video or access is denied". Any assistance you can provide would be helpful.
gordon12393
 
Posts: 7
Joined: Fri Jan 07, 2011 4:41 am

I also get a 'Video not found or access denied' error

Postby bufordt » Fri Apr 01, 2011 9:13 pm

gordon12393 wrote:diego_dambra,

I added this script to my ubuntu system with subsonic. When I try to play a video I get an error stating "cannot find video or access is denied". Any assistance you can provide would be helpful.


Has anyone successfully gotten this to work?
bufordt
 
Posts: 1
Joined: Fri Apr 01, 2011 9:04 pm

Re: Using VLC to transcode video to H.264/AAC

Postby achoo5000 » Mon Apr 04, 2011 6:46 am

calvintml wrote:have you by any chance updated your vlc.pl script to support skipping to different times in a video (as is currently possible with ffmpeg)?


I was able to edit the vlc.pl file to enable skipping.

Code: Select all
#!/usr/bin/perl
#safety
use strict;
use warnings;

#includes
use Getopt::Long;

#secure shell
$ENV{'PATH'} = '/bin:/usr/bin';
delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};

=head1 NAME

vlc.pl - transcode input stream to H.264/AAC TS stream

=head1 VERSION

Version 0.01

=cut

my $VERSION = "0.01";

=head1 SYNOPSIS

Transcode video stream to H.264/AAC TS

To use it, do:

    vlc.pl -h

=head1 EXPORT

All private methods listed below.

=head1 SUBROUTINES/METHODS

=cut

#help text
sub usage {
    print <<"EOT";
Usage: vlc.pl [ options ]

    -i, --input STREAM
        Path to input stream, e.g. file, URL or anything else VLC supports as input
        (default: STDIN)

    -t, --type NAME
        Type of output stream, supported are LiveHTTP, RTSP, HTTP or STDOUT
        (default: STDOUT)

    --canvas WIDTH:HEIGHT or WIDTHxHEIGHT
        Width and height of output stream
        (default: 480:320)

    --video-bit VALUE
        Max video bit rate, higher value produces better quality at the expense of CPU and bandwidth
        (default: 512)

    --audio-bit VALUE
        Max audio bit rate, higher value produces better quality at the expense of CPU and bandwidth
        (default: 128)
       
    --audio-sample-rate VALUE
        Audio sample rate, higher value produces better quality at the expense of CPU and bandwidth
        (default: 22050)

    --audio-channels VALUE
        Number of audio channels, higher value produces better quality at the expense of CPU and bandwidth
        (default: 2)

    --start-offset VALUE
        Start time offset in seconds, skips to time in file to start transcoding.

    -w, --www HOST:PORT
        Required host and port when creating LiveHTTP, RTSP or HTTP stream
        Example: mydomain.com:8080

    --www-folder PATH
        Path to www folder where VLC will save .m3u3 or .sdp file, if type is LiveHTTP or RTSP
        (default: /var/www)

    --transcode STRING
        VLC transcodeing commands, expert option only use this if you really known what you're doing

    --mux TYPE
        Output stream MUX (mp4 or flv), expert option only use this if you really known what you're doing
        (default: flv)

    --username NAME
        VLC will not run as user root, run process as this user
        (default: current_user)
       
    --version
        Show version information
       
    --help
        This message

Example:

EOT
    exit 0;
}

#vars we need
my $transcode =
    '#transcode{venc=x264{profile=baseline,level=3,keyint=50,bframes=0,no-cabac,ref=1,'
  . 'no-interlaced,vbv-maxrate=VIDEOBITRATE,vbv-bufsize=512,aq-mode=0,no-mbtree,partitions=none,'
  . 'no-weightb,weightp=0,me=umh,subme=0,no-mixed-refs,no-8x8dct,trellis=0},vcodec=h264,'
  . 'vb=VIDEOBITRATE,vfilter=canvas{width=WIDTH,height=HEIGHT,aspect=CANVAS,padd},'
  . 'aenc=ffmpeg{aac-profile=low},acodec=mp4a,ab=AUDIOBITRATE,channels=AUDIOCHANNELS,audio-sync,'
  . 'samplerate=AUDIOSAMPLERATE}';
my $input = '-';
my $type  = 'STDOUT';
my $host_port;
my $canvas   = '480:320';
my $vb       = 512;
my $ab       = 128, my $as = 22050;
my $ac       = 2;
my $www_path = '/var/www';
my $username;
my $mux = 'flv';
my $starttime = 0;

#get arguments
GetOptions(
    'i|input=s'           => \$input,
    't|type=s'            => \$type,
    'w|www=s'             => \$host_port,
    'canvas=s'            => \$canvas,
    'video-bit=i'         => \$vb,
    'audio-bit=i'         => \$ab,
    'audio-sample-rate=i' => \$as,
    'audio-channels=i'    => \$ac,
    'start-offset=f'      => \$starttime,
    'www-folder=s'        => \$www_path,
    'transcode=s'         => \$transcode,
    'username=s'          => \$username,
    'mux=s'               => \$mux,
    'help'                => \&usage,
    'version' => sub { print "Setup VLC to transcode video stream to H.264/AAC - version $VERSION\n"; exit 0; },
) || &usage;

#check environment
my $vlc_cmd = `which cvlc`;
die "FATAL: unable to locate needed VLC util: cvlc - please install it to use this script..."
  unless ($vlc_cmd);

#convert canvas
$canvas =~ s/x/:/ if ( defined($canvas) );

#setup VLC
setup_vlc( $input, $type, $host_port, $canvas, $vb, $ab, $as, $ac, $www_path, $transcode, $username, $mux , $starttime);

=head2 setup_vlc($input, $type, $host_port, $canvas, $vb, $ab, $as, $ac, $www_path, $transcode, $username)

    Setup VLC steam
    arg0: str with input stream
    arg1: str with type stream to create, LiveHTTP, RTSP, HTTP or STDOUT
    arg2: str with hostname and port (e.g. 0.0.0.0:5554 or host.domain.com:8080)
    arg3: str with width:height stream canvas size/aspect (default: 480:320)
    arg4: int with video bitrate, kb/s (default: 512)
    arg5: int with audio bitrate, kb/s (default: 128)
    arg6: int with audio samplerate (default 22050)
    arg7: int with number of audio channels (default: 2)
    arg8: str with path to www folder (default: /var/www)
    arg9: str with transcode arguments
    arg10: str with username
    arg11: str with mux
    arg12: float with start offset (default: 0)
    ret0: str with URL to stream
   
=cut

sub setup_vlc {
    my $input          = shift;                  #arg0
    my $type           = shift;                  #arg1
    my $host_port      = shift;                  #arg2
    my $canvas         = shift || '480:320';     #arg3
    my $vb             = shift || 512;           #arg4
    my $ab             = shift || 128;           #arg5
    my $as             = shift || 22050;         #arg6
    my $ac             = shift || 2;             #arg7
    my $www_path       = shift || '/var/www';    #arg8
    my $transcode_args = shift;                  #arg9
    my $username       = shift;                  #arg10
    my $mux            = shift;                  #arg11
    my $starttime      = shift || 0;             #arg12

    #validate arguments
    die "FATAL: missing input stream type, e.g. udp://\@:5000" unless ( defined($input) );
    die "FATAL: un-supported stream format: <$type>"
      unless ( defined($type) && ( $type eq 'LiveHTTP' || $type eq 'RTSP' || $type eq 'HTTP' || $type eq 'STDOUT' ) );
    die "FATAL: hostname and/or port malformed: <$host_port>"
      unless ( ( defined($host_port) && $host_port =~ /^[\.\w]+:\d+$/ ) || $type eq 'STDOUT' );
    die "FATAL: un-supported canvas size: <$canvas>" unless ( $canvas =~ /^\d+:\d+$/ );
    die "FATAL: un-supported video bitrate: <$vb>"   unless ( $vb     =~ /^\d+$/ );
    die "FATAL: unable to use path: <$www_path>" if ( $type eq 'LiveHTTP' && !-d "$www_path" );
    die "FATAL: missing transcode options" unless ( defined($transcode_args) );
    die "FATAL: not a valid mux: <$mux>" unless ( defined($mux) && ( $mux eq 'flv' || $mux eq 'mp4' ) );

    #set canvas width and height
    my ( $width, $height ) = split( /:/, $canvas, 2 );

    #VLC arguments
    my $vlc_default_args = '--intf dummy --ipv4 --no-inhibit';
    my $vlc_sout_arg     = $transcode_args;

    #replace markers
    $vlc_sout_arg =~ s/VIDEOBITRATE/$vb/g;
    $vlc_sout_arg =~ s/WIDTH/$width/g;
    $vlc_sout_arg =~ s/HEIGHT/$height/g;
    $vlc_sout_arg =~ s/CANVAS/$canvas/g;
    $vlc_sout_arg =~ s/AUDIOBITRATE/$ab/g;
    $vlc_sout_arg =~ s/AUDIOSAMPLERATE/$as/g;
    $vlc_sout_arg =~ s/AUDIOCHANNELS/$ac/g;

    #VLC output stream
    my $vlc_out;
    my $url;
    if ( $type eq 'LiveHTTP' ) {
        $url     = "http://$www_path/vlc.m3u8";
        $vlc_out = "standard{access=livehttp{seglen=10,delsegs=true,numsegs=5,index=$www_path/vlc.m3u8,"
          . "index-url=http://$host_port/vlc-######.ts},mux=ts{use-key-frames},dst=$www_path/vlc-######.ts}";
    }
    elsif ( $type eq 'HTTP' ) {
        $url     = "http://$host_port";
        $vlc_out = "standard{access=http,mux=ts,dst=$host_port}";
    }
    elsif ( $type eq 'RTSP' ) {
        $url     = "rtsp://$host_port/vlc.sdp";
        $vlc_out = "rtp{sdp=rtsp://$host_port/vlc.sdp,mp4a-latm}";
    }
    else {
        $url = '-';
        my $out_mux;
        if ( $mux eq 'flv' ) {
            $out_mux = 'ffmpeg{mux=flv}';
        }
        else {
            $out_mux = 'mp4';
        }
        $vlc_out = "standard{access=file,mux=$out_mux,dst=-}";
    }

    #start VLC
    my $vlc = ( defined($username) ? "sudo -u $username " : '' ) . "cvlc";
    my $vlc_cmd = "$vlc $input -q $vlc_default_args --start-time=$starttime :sout="$vlc_sout_arg:$vlc_out" vlc://quit 2>/dev/null";
    print "$url\n" unless ( $type eq 'STDOUT' );
    system($vlc_cmd);

    #return url
    return ($url);
}

=head1 ACKNOWLEDGEMENTS


=head1 LICENSE AND COPYRIGHT

Copyright 2010/2011 Diego d'Ambra (diegoatdambra.dk) / Nikolaj Steensgaard (nikolajatsteensgaard.net)

This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.

=cut


The transcode rule should now use:

Code: Select all
vlc.pl -i '%s' --canvas %wx%h --video-bit %b --username NONROOTUSER --start-offset %o


For me it's not a working solution yet, audio is not streaming, and when the stream is closed (by navigating to another page in subsonic) the vlc process remains, eating up the cpu.

Anyone have ideas about why audio wouldn't stream or why vlc isn't getting killed when the stream dies? (how does it work for ffmpeg?)
Last edited by achoo5000 on Mon Apr 04, 2011 6:55 am, edited 1 time in total.
achoo5000
 
Posts: 29
Joined: Wed Mar 30, 2011 10:47 pm
Location: USA

Postby achoo5000 » Mon Apr 04, 2011 6:51 am

gordon12393 wrote:diego_dambra,

I added this script to my ubuntu system with subsonic. When I try to play a video I get an error stating "cannot find video or access is denied". Any assistance you can provide would be helpful.


Does the user that is running vlc have read privileges to the file?
achoo5000
 
Posts: 29
Joined: Wed Mar 30, 2011 10:47 pm
Location: USA

Postby GJ51 » Tue Jun 07, 2011 12:33 am

I've been able to get some pretty good video results on Windows by installing a later ffmpeg build from http://ffmpeg.zeranoe.com/builds/ this allows ffmpeg to use more than one core for transcoding which pretty much cures the spinning wheel.

Select either the 32 or 64 bit Static Build. Just unpack with 7-Zip and place the ffmpeg.exe in the C:\Subsonic\transcode directory.

i also update to the 5.6 JW Player. Sample video is available on my site listed below.
Gary J

http://bios-mods.com
http://www.maplegrovepartners.com
http://theaverageguy.tv/category/tagpodcasts/cyberfrontiers/
User avatar
GJ51
 
Posts: 3492
Joined: Wed Oct 20, 2010 11:58 pm
Location: Western New York

Postby muiz » Tue Jun 07, 2011 11:16 pm

how make this work in windows?
muiz
 
Posts: 86
Joined: Wed Feb 02, 2011 11:52 am

Postby GJ51 » Tue Jun 07, 2011 11:31 pm

Subsonic Player and ffmpeg update

To update JW Player to the newest version, go to http://forum.subsonic.org/forum/viewtopic.php?t=5977

and read the instructions. Read the whole thread as you'll see there is the long way and the short way. I use the method I suggested as it seemed to be less time consuming. IF I want to know what version of the player I'm running, I'll just fo a right click on the installed player and it will tell me what version it is.

I just downloaded JW 5.6, extract player.swf, rename it to the current name in the subsonic/jetty/xxxx/webapp/flash folder and replace the original file. Rename JW Player 5.4 to Old JW Player 5.4. then drop player.swf into the directory and rename it to JW Player 5.4 when you're done it'll be named 5.4 but if you right click on it in SS you'll se that it's really 5.6

ffmpeg - go to http://ffmpeg.zeranoe.com/builds/ and download the latest static build for your system. This site is for Windows builds. Check http://www.ffmpeg.org/download.html for other OS's. I just extracted the ffmpeg.exe and replaced thet file in C:\Subsonic\transcode
Gary J

http://bios-mods.com
http://www.maplegrovepartners.com
http://theaverageguy.tv/category/tagpodcasts/cyberfrontiers/
User avatar
GJ51
 
Posts: 3492
Joined: Wed Oct 20, 2010 11:58 pm
Location: Western New York

Not working

Postby qwertman » Sat Aug 06, 2011 4:53 am

Why is the perl script necessary? Why can't the vlc command be in subsonic?

I had an EOT not found before EOF error in the perl script. I fixed that and got rid of the sudo string since I'm running subsonic as a non-root user, but the script isn't working. If I try to run it from the command line it returns nothing, and if I try to use it from Subsonic I get the standard Video Not Found error.
qwertman
 
Posts: 6
Joined: Wed Mar 30, 2011 1:55 pm
Location: Michigan


Return to Mods, Apps and Clients

Who is online

Users browsing this forum: No registered users and 3 guests