diff --git a/helpers/DATA/vlc/46fe18b280ed5825fd701edeedb2f5c24de001a2_without_xiph.patch b/helpers/DATA/vlc/46fe18b280ed5825fd701edeedb2f5c24de001a2_without_xiph.patch
new file mode 100644
index 0000000000000000000000000000000000000000..204ca92730204ce8a15af7411a6801308295c6a9
--- /dev/null
+++ b/helpers/DATA/vlc/46fe18b280ed5825fd701edeedb2f5c24de001a2_without_xiph.patch
@@ -0,0 +1,243 @@
+From 46fe18b280ed5825fd701edeedb2f5c24de001a2 Mon Sep 17 00:00:00 2001
+From: Denis Charmet <typx@dinauz.org>
+Date: Sat, 9 Nov 2013 16:53:06 +0100
+Subject: [PATCH] Implement basic Opus support in MKV
+
+---
+ modules/codec/opus.c                         |  5 ++++
+ modules/demux/mkv/matroska_segment.cpp       | 22 +++++++++++++++-
+ modules/demux/mkv/matroska_segment_parse.cpp | 36 +++++++++++++++++++++++++
+ modules/demux/mkv/mkv.cpp                    | 39 +++++++++++++++++++---------
+ modules/demux/mkv/mkv.hpp                    |  6 +++--
+ 5 files changed, 94 insertions(+), 16 deletions(-)
+
+diff --git a/modules/codec/opus.c b/modules/codec/opus.c
+index d4e5f88..8802d49 100644
+--- a/modules/codec/opus.c
++++ b/modules/codec/opus.c
+@@ -386,6 +386,11 @@ static block_t *DecodePacket( decoder_t *p_dec, ogg_packet *p_oggpacket,
+     if(spp>0)spp*=opus_packet_get_samples_per_frame(p_oggpacket->packet,48000);
+     if(spp<120||spp>120*48)return NULL;
+ 
++    /* Since the information isn't always available at the demux level
++     * use the packet's sample number */
++    if(!i_nb_samples)
++        i_nb_samples = spp;
++
+     block_t *p_aout_buffer=decoder_NewAudioBuffer( p_dec, spp );
+     if ( !p_aout_buffer )
+     {
+diff --git a/modules/demux/mkv/matroska_segment.cpp b/modules/demux/mkv/matroska_segment.cpp
+index 756a9c5..5e71206 100644
+--- a/modules/demux/mkv/matroska_segment.cpp
++++ b/modules/demux/mkv/matroska_segment.cpp
+@@ -929,10 +929,22 @@ void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_
+     /* now parse until key frame */
+     const int es_types[3] = { VIDEO_ES, AUDIO_ES, SPU_ES };
+     i_cat = es_types[0];
++    mtime_t i_seek_preroll = 0;
+     for( int i = 0; i < 2; i_cat = es_types[++i] )
+     {
+         for( i_track = 0; i_track < tracks.size(); i_track++ )
+         {
++            if( tracks[i_track]->i_seek_preroll )
++            {
++                bool b_enabled;
++                if( es_out_Control( sys.demuxer.out,
++                                    ES_OUT_GET_ES_STATE,
++                                    tracks[i_track]->p_es,
++                                    &b_enabled ) == VLC_SUCCESS &&
++                    b_enabled )
++                    i_seek_preroll = __MAX( i_seek_preroll,
++                                            tracks[i_track]->i_seek_preroll );
++            }
+             if( tracks[i_track]->fmt.i_cat == i_cat )
+             {
+                 spoint * seekpoint = new spoint(i_track, i_seek_time, i_seek_position, i_seek_position);
+@@ -968,7 +980,7 @@ void matroska_segment_c::Seek( mtime_t i_date, mtime_t i_time_offset, int64_t i_
+         es_out_Control( sys.demuxer.out, ES_OUT_SET_NEXT_DISPLAY_TIME, i_date );
+         return;
+     }
+-
++    i_date -= i_seek_preroll;
+     for(;;)
+     {
+         do
+@@ -1201,6 +1213,7 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
+     *pb_key_picture         = true;
+     *pb_discardable_picture = false;
+     size_t i_tk;
++    *pi_duration = 0;
+ 
+     for( ;; )
+     {
+@@ -1407,6 +1420,13 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
+                             }
+                         }
+                     }
++#if LIBMATROSKA_VERSION >= 0x010401
++                    else if( MKV_IS_ID( el, KaxDiscardPadding ) )
++                    {
++                        KaxDiscardPadding &dp = *(KaxDiscardPadding*) el;
++                        *pi_duration -= int64(dp);
++                    }
++#endif
+                     break;
+                 default:
+                     msg_Err( &sys.demuxer, "invalid level = %d", i_level );
+diff --git a/modules/demux/mkv/matroska_segment_parse.cpp b/modules/demux/mkv/matroska_segment_parse.cpp
+index c9d2c9d..7b4c359 100644
+--- a/modules/demux/mkv/matroska_segment_parse.cpp
++++ b/modules/demux/mkv/matroska_segment_parse.cpp
+@@ -30,6 +30,7 @@
+ 
+ extern "C" {
+ #include "../vobsub.h"
++#include "../xiph.h"
+ }
+ 
+ #include <vlc_codecs.h>
+@@ -401,6 +402,21 @@ void matroska_segment_c::ParseTrackEntry( KaxTrackEntry *m )
+ 
+             msg_Dbg( &sys.demuxer, "|   |   |   + Track Overlay=%u", uint32( tovr ) );
+         }
++#if LIBMATROSKA_VERSION >= 0x010401
++        else if( MKV_IS_ID( l, KaxCodecDelay ) )
++        {
++            KaxCodecDelay &codecdelay = *(KaxCodecDelay*)l;
++            tk->i_codec_delay = uint64_t( codecdelay ) / 1000;
++            msg_Dbg( &sys.demuxer, "|   |   |   + Track Codec Delay =%"PRIu64,
++                     tk->i_codec_delay );
++        }
++        else if( MKV_IS_ID( l, KaxSeekPreRoll ) )
++        {
++            KaxSeekPreRoll &spr = *(KaxSeekPreRoll*)l;
++            tk->i_seek_preroll = uint64_t(spr) / 1000;
++            msg_Dbg( &sys.demuxer, "|   |   |   + Track Seek Preroll =%"PRIu64, tk->i_seek_preroll );
++        }
++#endif
+         else if( MKV_IS_ID( l, KaxContentEncodings ) )
+         {
+             EbmlMaster *cencs = static_cast<EbmlMaster*>(l);
+@@ -1477,6 +1493,26 @@ int32_t matroska_segment_c::TrackInit( mkv_track_t * p_tk )
+         p_tk->fmt.i_codec = VLC_CODEC_VORBIS;
+         fill_extra_data( p_tk, 0 );
+     }
++    else if( !strncmp( p_tk->psz_codec, "A_OPUS", 6 ) )
++    {
++        p_tk->fmt.i_codec = VLC_CODEC_OPUS;
++        if( !p_tk->fmt.audio.i_rate )
++        {
++            msg_Err( &sys.demuxer,"No sampling rate, defaulting to 48kHz");
++            p_tk->fmt.audio.i_rate = 48000;
++        }
++        const uint8_t tags[16] = {'O','p','u','s','T','a','g','s',
++                                   0, 0, 0, 0, 0, 0, 0, 0};
++        unsigned ps[2] = { p_tk->i_extra_data, 16 };
++        const void *pkt[2] = { (const void *)p_tk->p_extra_data,
++                              (const void *) tags };
++
++        if( xiph_PackHeaders( &p_tk->fmt.i_extra,
++                              &p_tk->fmt.p_extra,
++                              ps, pkt, 2 ) )
++            msg_Err( &sys.demuxer, "Couldn't pack OPUS headers");
++
++    }
+     else if( !strncmp( p_tk->psz_codec, "A_AAC/MPEG2/", strlen( "A_AAC/MPEG2/" ) ) ||
+              !strncmp( p_tk->psz_codec, "A_AAC/MPEG4/", strlen( "A_AAC/MPEG4/" ) ) )
+     {
+diff --git a/modules/demux/mkv/mkv.cpp b/modules/demux/mkv/mkv.cpp
+index 6398409..7d42d83 100644
+--- a/modules/demux/mkv/mkv.cpp
++++ b/modules/demux/mkv/mkv.cpp
+@@ -499,10 +499,8 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
+         msg_Err( p_demux, "unknown track number" );
+         return;
+     }
+-    if( i_pts + i_duration < p_sys->i_start_pts && tk->fmt.i_cat == AUDIO_ES )
+-    {
+-        return; /* discard audio packets that shouldn't be rendered */
+-    }
++
++    i_pts -= tk->i_codec_delay;
+ 
+     if ( tk->fmt.i_cat != NAV_ES )
+     {
+@@ -592,9 +590,10 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
+         {
+             memcpy( p_block->p_buffer, tk->p_compression_data->GetBuffer(), tk->p_compression_data->GetSize() );
+         }
+-
+-        if( tk->fmt.i_codec == VLC_CODEC_COOK ||
+-            tk->fmt.i_codec == VLC_CODEC_ATRAC3 )
++        switch( tk->fmt.i_codec )
++        {
++        case VLC_CODEC_COOK:
++        case VLC_CODEC_ATRAC3:
+         {
+             handle_real_audio(p_demux, tk, p_block, i_pts);
+             block_Release(p_block);
+@@ -602,6 +601,27 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
+                 i_pts + ( mtime_t )( tk->i_default_duration / 1000 ):
+                 VLC_TS_INVALID;
+             continue;
++         }
++         case VLC_CODEC_SPU:
++            if( strcmp( tk->psz_codec, "S_VOBSUB" ) )
++                p_block->i_length = i_duration * tk-> f_timecodescale *
++                    (double) p_segment->i_timescale / 1000.0;
++            break;
++         case VLC_CODEC_OPUS:
++            if( i_duration > 0 )
++            {
++                mtime_t i_length = i_duration * tk-> f_timecodescale *
++                    (double) p_segment->i_timescale / 1000.0;
++                p_block->i_nb_samples = i_length * tk->fmt.audio.i_rate
++                     / CLOCK_FREQ;
++                break;
++            }
++            else if( i_duration < 0 )
++            {
++                /* Opus uses p_block->i_length to handle discard padding */
++                p_block->i_length = -1 * i_duration * tk->fmt.audio.i_rate
++                    / CLOCK_FREQ;
++            }
+         }
+ 
+         if ( tk->fmt.i_cat == NAV_ES )
+@@ -643,11 +663,6 @@ void BlockDecode( demux_t *p_demux, KaxBlock *block, KaxSimpleBlock *simpleblock
+ #if 0
+ msg_Dbg( p_demux, "block i_dts: %"PRId64" / i_pts: %"PRId64, p_block->i_dts, p_block->i_pts);
+ #endif
+-        if( strcmp( tk->psz_codec, "S_VOBSUB" ) )
+-        {
+-            p_block->i_length = i_duration * tk-> f_timecodescale * (double) p_segment->i_timescale / 1000.0;
+-        }
+-
+         /* FIXME remove when VLC_TS_INVALID work is done */
+         if( i == 0 || p_block->i_dts > VLC_TS_INVALID )
+             p_block->i_dts += VLC_TS_0;
+diff --git a/modules/demux/mkv/mkv.hpp b/modules/demux/mkv/mkv.hpp
+index efc88b3..7cae3e7 100644
+--- a/modules/demux/mkv/mkv.hpp
++++ b/modules/demux/mkv/mkv.hpp
+@@ -188,8 +188,6 @@ class PrivateTrackData
+ 
+ struct mkv_track_t
+ {
+-//    ~mkv_track_t();
+-
+     bool         b_default;
+     bool         b_enabled;
+     bool         b_forced;
+@@ -237,6 +235,10 @@ struct mkv_track_t
+     uint32_t               i_encoding_scope;
+     KaxContentCompSettings *p_compression_data;
+ 
++    /* Matroska 4 new elements used by Opus */
++    mtime_t i_seek_preroll;
++    mtime_t i_codec_delay;
++
+ };
+ 
+ struct mkv_index_t
diff --git a/helpers/make-vlc b/helpers/make-vlc
new file mode 100644
index 0000000000000000000000000000000000000000..cb155a9d97c4b999d27f82fcda50656d41da6b41
--- /dev/null
+++ b/helpers/make-vlc
@@ -0,0 +1,29 @@
+#!/bin/sh
+#
+#    Copyright (C) 2015  Santiago Rodríguez <santi@trisquel.info>
+#
+#    This program is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation; either version 2 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+#
+
+VERSION=1
+
+. ./config
+
+#Enable OPUS support in mkv container
+patch -p1 < $DATA/46fe18b280ed5825fd701edeedb2f5c24de001a2_without_xiph.patch
+
+changelog "Added opus support to mkv container"
+
+compile