Patchwork [1/1] package/tvheadend: new package

login
register
mail settings
Submitter Yann E. MORIN
Date Dec. 24, 2012, 10 a.m.
Message ID <97b2cc572615e7c760fb8f351510b67ccb02a0e4.1356343037.git.yann.morin.1998@free.fr>
Download mbox | patch
Permalink /patch/208048/
State Changes Requested
Headers show

Comments

Yann E. MORIN - Dec. 24, 2012, 10 a.m.
Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
---
 package/Config.in                   |    1 +
 package/tvheadend/Config.in         |   20 +++++++++
 package/tvheadend/tvheadend.config  |   13 ++++++
 package/tvheadend/tvheadend.default |    6 +++
 package/tvheadend/tvheadend.init    |   54 +++++++++++++++++++++++++
 package/tvheadend/tvheadend.mk      |   76 +++++++++++++++++++++++++++++++++++
 package/tvheadend/tvheadend.mkuser  |   52 ++++++++++++++++++++++++
 7 files changed, 222 insertions(+), 0 deletions(-)
 create mode 100644 package/tvheadend/Config.in
 create mode 100644 package/tvheadend/tvheadend.config
 create mode 100644 package/tvheadend/tvheadend.default
 create mode 100644 package/tvheadend/tvheadend.init
 create mode 100644 package/tvheadend/tvheadend.mk
 create mode 100755 package/tvheadend/tvheadend.mkuser
Yann E. MORIN - Dec. 24, 2012, 1:15 p.m.
Hello All, Maxime,

On Monday 24 December 2012 Yann E. MORIN wrote:
[--SNIP--]
> diff --git a/package/tvheadend/tvheadend.mk b/package/tvheadend/tvheadend.mk
> new file mode 100644
> index 0000000..d2fe97a
> --- /dev/null
> +++ b/package/tvheadend/tvheadend.mk
> @@ -0,0 +1,76 @@
[--SNIP--]
> +define TVHEADEND_INSTALL_SYSV_STARTUP_FILES
> +	$(INSTALL) -D package/tvheadend/tvheadend.default $(TARGET_DIR)/etc/default/tvheadend
> +	$(INSTALL) -D package/tvheadend/tvheadend.init    $(TARGET_DIR)/etc/init.d/S99tvheadend
> +endef
> +TVHEADEND_INSTALL_INIT_SYSV          = TVHEADEND_INSTALL_SYSV_STARTUP_FILES

I just forgot to rebuild after this change. It's broken, of course.
I've now fixed it and pushed the new package. Sorry for the confusion.

Regards,
Yann E. MORIN.
Peter Korsgaard - Dec. 26, 2012, 10:26 p.m.
>>>>> "Yann" == Yann E MORIN <yann.morin.1998@free.fr> writes:

Hi,

 Yann> Signed-off-by: "Yann E. MORIN" <yann.morin.1998@free.fr>
 Yann> ---
 Yann>  package/Config.in                   |    1 +
 Yann>  package/tvheadend/Config.in         |   20 +++++++++
 Yann>  package/tvheadend/tvheadend.config  |   13 ++++++
 Yann>  package/tvheadend/tvheadend.default |    6 +++
 Yann>  package/tvheadend/tvheadend.init    |   54 +++++++++++++++++++++++++
 Yann>  package/tvheadend/tvheadend.mk      |   76 +++++++++++++++++++++++++++++++++++
 Yann>  package/tvheadend/tvheadend.mkuser  |   52 ++++++++++++++++++++++++
 Yann>  7 files changed, 222 insertions(+), 0 deletions(-)
 Yann>  create mode 100644 package/tvheadend/Config.in
 Yann>  create mode 100644 package/tvheadend/tvheadend.config
 Yann>  create mode 100644 package/tvheadend/tvheadend.default
 Yann>  create mode 100644 package/tvheadend/tvheadend.init
 Yann>  create mode 100644 package/tvheadend/tvheadend.mk
 Yann>  create mode 100755 package/tvheadend/tvheadend.mkuser

 Yann> diff --git a/package/Config.in b/package/Config.in
 Yann> index 3d556b2..bcf0009 100644
 Yann> --- a/package/Config.in
 Yann> +++ b/package/Config.in
 Yann> @@ -682,6 +682,7 @@ source "package/tinyhttpd/Config.in"
 Yann>  source "package/tn5250/Config.in"
 Yann>  source "package/transmission/Config.in"
 Yann>  source "package/ttcp/Config.in"
 Yann> +source "package/tvheadend/Config.in"
 Yann>  source "package/udpcast/Config.in"
 Yann>  source "package/ulogd/Config.in"
 Yann>  source "package/ushare/Config.in"
 Yann> diff --git a/package/tvheadend/Config.in b/package/tvheadend/Config.in
 Yann> new file mode 100644
 Yann> index 0000000..679ca13
 Yann> --- /dev/null
 Yann> +++ b/package/tvheadend/Config.in
 Yann> @@ -0,0 +1,20 @@
 Yann> +comment "tvheadend requires a toolchain with WCHAR"

We normally add ' support' - E.G. WCHAR support.

It also needs largefile support unless you override CFLAGS in the
Makefile:

Makefile:CFLAGS  += -D_FILE_OFFSET_BITS=64


 Yann> +++ b/package/tvheadend/tvheadend.default
 Yann> @@ -0,0 +1,6 @@
 Yann> +TVH_USER=tvheadend
 Yann> +TVH_GROUP=tvheadend
 Yann> +#TVH_ADAPTERS=
 Yann> +#TVH_HTTP_PORT=9981
 Yann> +#TVH_HTSP_PORT=9982
 Yann> +#TVH_DEBUG=1
 Yann> diff --git a/package/tvheadend/tvheadend.init b/package/tvheadend/tvheadend.init
 Yann> new file mode 100644
 Yann> index 0000000..b05ec81
 Yann> --- /dev/null
 Yann> +++ b/package/tvheadend/tvheadend.init
 Yann> @@ -0,0 +1,54 @@
 Yann> +#! /bin/sh
 Yann> +# Startup script inspired by the one in the package

It would be good to mention 'tvheadend' here.


 Yann> +++ b/package/tvheadend/tvheadend.mk
 Yann> @@ -0,0 +1,76 @@
 Yann> +#############################################################
 Yann> +#
 Yann> +# tvheadend
 Yann> +#
 Yann> +##############################################################
 Yann> +
 Yann> +TVHEADEND_VERSION           = v3.3
 Yann> +TVHEADEND_SITE              = http://github.com/tvheadend/tvheadend/tarball/$(TVHEADEND_VERSION)
 Yann> +TVHEADEND_LICENSE           = GPLv3+
 Yann> +TVHEADEND_LICENSE_FILES     = LICENSE
 Yann> +TVHEADEND_DEPENDENCIES      = host-pkgconf openssl python
 Yann> +
 Yann> +ifeq ($(BR2_PACKAGE_AVAHI),y)
 Yann> +TVHEADEND_DEPENDENCIES     += avahi
 Yann> +endif
 Yann> +
 Yann> +#----------------------------------------------------------------------------
 Yann> +# tvheadend is a little smuggler and thief! ;-)
 Yann> +# During the ./configure, it downloads some files from the dvb-apps
 Yann> +# package, so it has a list of pre-scanned tunner configurations.
 Yann> +# For buildroot that has a few-unfortunate consequences:
 Yann> +#  - the network may not be availabe at the time of build, if the
 Yann> +#    user pre-downloaded the sources with 'make source'
 Yann> +# So, here's what we do:
 Yann> +#  - after the main archive download, we do download those files
 Yann> +#  - after extract, we extract the required files
 Yann> +
 Yann> +TVHEADEND_DVBSCANS_VERSION  = 3fc7dfa68484
 Yann> +TVHEADEND_DVBSCANS_SITE     = http://linuxtv.org/hg/dvb-apps/archive/
 Yann> +TVHEADEND_DVBSCANS_DIR      = dvb-apps-$(TVHEADEND_DVBSCANS_VERSION)
 Yann> +TVHEADEND_DVBSCANS_SOURCE   = $(TVHEADEND_DVBSCANS_DIR).tar.bz2
 Yann> +
 Yann> +define TVHEADEND_DOWNLOAD_DVBSCANS
 Yann> +	$(call DOWNLOAD_WGET,$(TVHEADEND_DVBSCANS_SITE)/$(TVHEADEND_DVBSCANS_VERSION).tar.bz2,$(TVHEADEND_DVBSCANS_SOURCE))
 Yann> +endef
 Yann> +TVHEADEND_POST_DOWNLOAD_HOOKS        = TVHEADEND_DOWNLOAD_DVBSCANS
 Yann> +
 Yann> +define TVHEADEND_EXTRACT_DVBSCANS
 Yann> +	mkdir -p $(@D)/data/dvb-scan
 Yann> +	$(INFLATE.bz2) $(DL_DIR)/$(TVHEADEND_DVBSCANS_SOURCE)      |\
 Yann> +	$(TAR) $(TAR_STRIP_COMPONENTS)=3 -C $(@D)/data/dvb-scan     \
 Yann> +	       $(TAR_OPTIONS) -                                     \
 Yann> +	       $(TVHEADEND_DVBSCANS_DIR)/util/scan/{atsc,dvb-{c,s,t}}
 Yann> +endef
 Yann> +TVHEADEND_POST_EXTRACT_HOOKS         = TVHEADEND_EXTRACT_DVBSCANS
 Yann> +
 Yann> +#----------------------------------------------------------------------------
 Yann> +# To run tvheadend, we need:
 Yann> +#  - a non-root user to be safe, with its owned ${HOME}
 Yann> +#  - a startup script, and its config file
 Yann> +#  - a default DB with a tvheadend admin
 Yann> +TVHEADEND_MKUSER = TARGET_DIR=$(TARGET_DIR) INSTALL=$(INSTALL) package/tvheadend/tvheadend.mkuser
 Yann> +define TVHEADEND_CREATE_USER
 Yann> +	$(TVHEADEND_MKUSER) mk_user
 Yann> +	$(INSTALL) -D package/tvheadend/tvheadend.config  $(TARGET_DIR)/home/tvheadend/.hts/tvheadend/accesscontrol/1
 Yann> +endef
 Yann> +TVHEADEND_POST_INSTALL_TARGET_HOOKS  = TVHEADEND_CREATE_USER
 Yann> +
 Yann> +define TVHEADEND_PERMISSIONS
 Yann> +	/home/tvheadend                                d 0700 $$(shell $(TVHEADEND_MKUSER) get_uid) $$(shell $(TVHEADEND_MKUSER) get_gid) - - - - -
 Yann> +	/home/tvheadend/.hts                           d 0700 $$(shell $(TVHEADEND_MKUSER) get_uid) $$(shell $(TVHEADEND_MKUSER) get_gid) - - - - -
 Yann> +	/home/tvheadend/.hts/tvheadend                 d 0700 $$(shell $(TVHEADEND_MKUSER) get_uid) $$(shell $(TVHEADEND_MKUSER) get_gid) - - - - -
 Yann> +	/home/tvheadend/.hts/tvheadend/accesscontrol   d 0700 $$(shell $(TVHEADEND_MKUSER) get_uid) $$(shell $(TVHEADEND_MKUSER) get_gid) - - - - -
 Yann> +	/home/tvheadend/.hts/tvheadend/accesscontrol/1 f 0600 $$(shell $(TVHEADEND_MKUSER) get_uid) $$(shell $(TVHEADEND_MKUSER) get_gid) - - - - -
 Yann> +endef

I'm not really happy about the user handling here. I think we should
either just add a static tvheadend user to system/skeleton/etc/passwd
like we've done for ssh/hal/dbus/.., or come up with some generic
infrastructure to handle it per package (like _PERMISSIONS) instead of
something tvheadend specific.

We also normally don't touch /home. Can't tvheadend run as system daemon
(still as a seperate user) instead?

 Yann> +
 Yann> +define TVHEADEND_INSTALL_SYSV_STARTUP_FILES
 Yann> +	$(INSTALL) -D package/tvheadend/tvheadend.default $(TARGET_DIR)/etc/default/tvheadend
 Yann> +	$(INSTALL) -D package/tvheadend/tvheadend.init    $(TARGET_DIR)/etc/init.d/S99tvheadend

I personally prefer to keep the same names both in package/ and
output/target (so S99tvheadend). Makes it easier to find the
corresponding source files.
Yann E. MORIN - Dec. 26, 2012, 11 p.m.
Peter, All,

On Wednesday 26 December 2012 Peter Korsgaard wrote:
> >>>>> "Yann" == Yann E MORIN <yann.morin.1998@free.fr> writes:
[--SNIP--]
>  Yann> diff --git a/package/tvheadend/Config.in b/package/tvheadend/Config.in
>  Yann> new file mode 100644
>  Yann> index 0000000..679ca13
>  Yann> --- /dev/null
>  Yann> +++ b/package/tvheadend/Config.in
>  Yann> @@ -0,0 +1,20 @@
>  Yann> +comment "tvheadend requires a toolchain with WCHAR"
> 
> We normally add ' support' - E.G. WCHAR support.

OK.

> It also needs largefile support unless you override CFLAGS in the
> Makefile:
> 
> Makefile:CFLAGS  += -D_FILE_OFFSET_BITS=64

LARGE_FILES that will be, then. ;-)

>  Yann> diff --git a/package/tvheadend/tvheadend.init b/package/tvheadend/tvheadend.init
>  Yann> new file mode 100644
>  Yann> index 0000000..b05ec81
>  Yann> --- /dev/null
>  Yann> +++ b/package/tvheadend/tvheadend.init
>  Yann> @@ -0,0 +1,54 @@
>  Yann> +#! /bin/sh
>  Yann> +# Startup script inspired by the one in the package
> 
> It would be good to mention 'tvheadend' here.

OK.

>  Yann> +++ b/package/tvheadend/tvheadend.mk
[--SNIP--]
>  Yann> +#----------------------------------------------------------------------------
>  Yann> +# To run tvheadend, we need:
>  Yann> +#  - a non-root user to be safe, with its owned ${HOME}
>  Yann> +#  - a startup script, and its config file
>  Yann> +#  - a default DB with a tvheadend admin
>  Yann> +TVHEADEND_MKUSER = TARGET_DIR=$(TARGET_DIR) INSTALL=$(INSTALL) package/tvheadend/tvheadend.mkuser
>  Yann> +define TVHEADEND_CREATE_USER
>  Yann> +	$(TVHEADEND_MKUSER) mk_user
>  Yann> +	$(INSTALL) -D package/tvheadend/tvheadend.config  $(TARGET_DIR)/home/tvheadend/.hts/tvheadend/accesscontrol/1
>  Yann> +endef
>  Yann> +TVHEADEND_POST_INSTALL_TARGET_HOOKS  = TVHEADEND_CREATE_USER
>  Yann> +
>  Yann> +define TVHEADEND_PERMISSIONS
>  Yann> +	/home/tvheadend                                d 0700 $$(shell $(TVHEADEND_MKUSER) get_uid) $$(shell $(TVHEADEND_MKUSER) get_gid) - - - - -
>  Yann> +	/home/tvheadend/.hts                           d 0700 $$(shell $(TVHEADEND_MKUSER) get_uid) $$(shell $(TVHEADEND_MKUSER) get_gid) - - - - -
>  Yann> +	/home/tvheadend/.hts/tvheadend                 d 0700 $$(shell $(TVHEADEND_MKUSER) get_uid) $$(shell $(TVHEADEND_MKUSER) get_gid) - - - - -
>  Yann> +	/home/tvheadend/.hts/tvheadend/accesscontrol   d 0700 $$(shell $(TVHEADEND_MKUSER) get_uid) $$(shell $(TVHEADEND_MKUSER) get_gid) - - - - -
>  Yann> +	/home/tvheadend/.hts/tvheadend/accesscontrol/1 f 0600 $$(shell $(TVHEADEND_MKUSER) get_uid) $$(shell $(TVHEADEND_MKUSER) get_gid) - - - - -
>  Yann> +endef
> 
> I'm not really happy about the user handling here. I think we should
> either just add a static tvheadend user to system/skeleton/etc/passwd
> like we've done for ssh/hal/dbus/..

That will make for an ever-increasing list of users, most will probably
never, ever be usefull. I do not like that... :-(

I agree however that the solution above is less than ideal.

> , or come up with some generic
> infrastructure to handle it per package (like _PERMISSIONS) instead of
> something tvheadend specific.

Yes, that's something I'm thinking about...

Basically, I'd expect something like:

TVHEADEND_USER = tvheadend -1 -1 /home/tvheadend /bin/sh
FOO_USER = USERNAME UID GID HOME SHELL

  - if UID (GID) is -1, then a uid (gid) will be choosen arbitrarily.
  - if UID (GID) is >=0 and conflicts with an other entry, the build fails
  - if HOME is 'none', no home is created for that user
  - if SHELL is 'none', then the shell will be set to /bin/false

Then:
  - an entry is created in /etc/passwd, and the home is created before the
    package is configured (except if home=='none')
  - the home is chowned (except if home=='none') using a generated
    _PERMISSIONS variable

> We also normally don't touch /home. Can't tvheadend run as system daemon
> (still as a seperate user) instead?

It still needs a place where to store:
  - its runtime configuration (that is done through the web interface and
    creates new files)
  - the recordings

>  Yann> +
>  Yann> +define TVHEADEND_INSTALL_SYSV_STARTUP_FILES
>  Yann> +	$(INSTALL) -D package/tvheadend/tvheadend.default $(TARGET_DIR)/etc/default/tvheadend
>  Yann> +	$(INSTALL) -D package/tvheadend/tvheadend.init    $(TARGET_DIR)/etc/init.d/S99tvheadend
> 
> I personally prefer to keep the same names both in package/ and
> output/target (so S99tvheadend). Makes it easier to find the
> corresponding source files.

OK.

Regards,
Yann E. MORIN.
Thomas Petazzoni - Dec. 27, 2012, 11:21 a.m.
Dear Yann E. MORIN,

On Mon, 24 Dec 2012 11:00:59 +0100, Yann E. MORIN wrote:

> +#----------------------------------------------------------------------------
> +# tvheadend is a little smuggler and thief! ;-)
> +# During the ./configure, it downloads some files from the dvb-apps
> +# package, so it has a list of pre-scanned tunner configurations.
> +# For buildroot that has a few-unfortunate consequences:
> +#  - the network may not be availabe at the time of build, if the
> +#    user pre-downloaded the sources with 'make source'
> +# So, here's what we do:
> +#  - after the main archive download, we do download those files
> +#  - after extract, we extract the required files
> +
> +TVHEADEND_DVBSCANS_VERSION  = 3fc7dfa68484
> +TVHEADEND_DVBSCANS_SITE     = http://linuxtv.org/hg/dvb-apps/archive/
> +TVHEADEND_DVBSCANS_DIR      = dvb-apps-$(TVHEADEND_DVBSCANS_VERSION)
> +TVHEADEND_DVBSCANS_SOURCE   = $(TVHEADEND_DVBSCANS_DIR).tar.bz2
> +
> +define TVHEADEND_DOWNLOAD_DVBSCANS
> +	$(call DOWNLOAD_WGET,$(TVHEADEND_DVBSCANS_SITE)/$(TVHEADEND_DVBSCANS_VERSION).tar.bz2,$(TVHEADEND_DVBSCANS_SOURCE))
> +endef
> +TVHEADEND_POST_DOWNLOAD_HOOKS        = TVHEADEND_DOWNLOAD_DVBSCANS
> +
> +define TVHEADEND_EXTRACT_DVBSCANS
> +	mkdir -p $(@D)/data/dvb-scan
> +	$(INFLATE.bz2) $(DL_DIR)/$(TVHEADEND_DVBSCANS_SOURCE)      |\
> +	$(TAR) $(TAR_STRIP_COMPONENTS)=3 -C $(@D)/data/dvb-scan     \
> +	       $(TAR_OPTIONS) -                                     \
> +	       $(TVHEADEND_DVBSCANS_DIR)/util/scan/{atsc,dvb-{c,s,t}}
> +endef
> +TVHEADEND_POST_EXTRACT_HOOKS         = TVHEADEND_EXTRACT_DVBSCANS

I think this part should be moved to a separate package, say
"dvb-apps", on which tvheadend would depend. It can install its stuff
in $(STAGING_DIR), for example, and then you can symlink
$(@D)/data/dvb-scan of tvheadend to the right directory in
$(STAGING_DIR), or better, modify a bit tvheadend so that it can take
an argument specifying where the dvb-data is to be found.

Best regards,

Thomas
Yann E. MORIN - Dec. 27, 2012, 11:41 a.m.
Thomas, All,

On Thursday 27 December 2012 Thomas Petazzoni wrote:
> On Mon, 24 Dec 2012 11:00:59 +0100, Yann E. MORIN wrote:
> > +#----------------------------------------------------------------------------
> > +# tvheadend is a little smuggler and thief! ;-)
> > +# During the ./configure, it downloads some files from the dvb-apps
> > +# package, so it has a list of pre-scanned tunner configurations.
> > +# For buildroot that has a few-unfortunate consequences:
> > +#  - the network may not be availabe at the time of build, if the
> > +#    user pre-downloaded the sources with 'make source'
> > +# So, here's what we do:
> > +#  - after the main archive download, we do download those files
> > +#  - after extract, we extract the required files
> > +
> > +TVHEADEND_DVBSCANS_VERSION  = 3fc7dfa68484
> > +TVHEADEND_DVBSCANS_SITE     = http://linuxtv.org/hg/dvb-apps/archive/
> > +TVHEADEND_DVBSCANS_DIR      = dvb-apps-$(TVHEADEND_DVBSCANS_VERSION)
> > +TVHEADEND_DVBSCANS_SOURCE   = $(TVHEADEND_DVBSCANS_DIR).tar.bz2
> > +
> > +define TVHEADEND_DOWNLOAD_DVBSCANS
> > +	$(call DOWNLOAD_WGET,$(TVHEADEND_DVBSCANS_SITE)/$(TVHEADEND_DVBSCANS_VERSION).tar.bz2,$(TVHEADEND_DVBSCANS_SOURCE))
> > +endef
> > +TVHEADEND_POST_DOWNLOAD_HOOKS        = TVHEADEND_DOWNLOAD_DVBSCANS
> > +
> > +define TVHEADEND_EXTRACT_DVBSCANS
> > +	mkdir -p $(@D)/data/dvb-scan
> > +	$(INFLATE.bz2) $(DL_DIR)/$(TVHEADEND_DVBSCANS_SOURCE)      |\
> > +	$(TAR) $(TAR_STRIP_COMPONENTS)=3 -C $(@D)/data/dvb-scan     \
> > +	       $(TAR_OPTIONS) -                                     \
> > +	       $(TVHEADEND_DVBSCANS_DIR)/util/scan/{atsc,dvb-{c,s,t}}
> > +endef
> > +TVHEADEND_POST_EXTRACT_HOOKS         = TVHEADEND_EXTRACT_DVBSCANS
> 
> I think this part should be moved to a separate package, say
> "dvb-apps", on which tvheadend would depend. It can install its stuff
> in $(STAGING_DIR), for example, and then you can symlink
> $(@D)/data/dvb-scan of tvheadend to the right directory in
> $(STAGING_DIR), or better, modify a bit tvheadend so that it can take
> an argument specifying where the dvb-data is to be found.

I knew this would raise eyebrows.
I'll see what I can come up with...

Regards,
Yann E. MORIN.

Patch

diff --git a/package/Config.in b/package/Config.in
index 3d556b2..bcf0009 100644
--- a/package/Config.in
+++ b/package/Config.in
@@ -682,6 +682,7 @@  source "package/tinyhttpd/Config.in"
 source "package/tn5250/Config.in"
 source "package/transmission/Config.in"
 source "package/ttcp/Config.in"
+source "package/tvheadend/Config.in"
 source "package/udpcast/Config.in"
 source "package/ulogd/Config.in"
 source "package/ushare/Config.in"
diff --git a/package/tvheadend/Config.in b/package/tvheadend/Config.in
new file mode 100644
index 0000000..679ca13
--- /dev/null
+++ b/package/tvheadend/Config.in
@@ -0,0 +1,20 @@ 
+comment "tvheadend requires a toolchain with WCHAR"
+	depends on !BR2_USE_WCHAR
+
+config BR2_PACKAGE_TVHEADEND
+	bool "tvheadend"
+	depends on BR2_USE_WCHAR    # python
+	depends on BR2_USE_MMU      # python
+	select BR2_PACKAGE_OPENSSL
+	select BR2_PACKAGE_PYTHON
+	help
+	  Tvheadend is a TV streaming server for Linux supporting DVB-S,
+	  DVB-S2, DVB-C, DVB-T, ATSC, IPTV, and Analog video (V4L) as
+	  input sources.
+	  
+	  https://www.lonelycoder.com/redmine/projects/tvheadend/
+	  
+	  Note: if you want Avahi support, you'll need to enable:
+	    - Avahi
+	    - D-Bus
+	    - libdaemon
diff --git a/package/tvheadend/tvheadend.config b/package/tvheadend/tvheadend.config
new file mode 100644
index 0000000..b920943
--- /dev/null
+++ b/package/tvheadend/tvheadend.config
@@ -0,0 +1,13 @@ 
+{
+        "enabled": 1,
+        "username": "admin",
+        "password": "admin",
+        "comment": "TVHeadend admin user",
+        "prefix": "0.0.0.0/0",
+        "streaming": 1,
+        "dvr": 1,
+        "dvrallcfg": 1,
+        "webui": 1,
+        "admin": 1,
+        "id": "1"
+}
diff --git a/package/tvheadend/tvheadend.default b/package/tvheadend/tvheadend.default
new file mode 100644
index 0000000..253f832
--- /dev/null
+++ b/package/tvheadend/tvheadend.default
@@ -0,0 +1,6 @@ 
+TVH_USER=tvheadend
+TVH_GROUP=tvheadend
+#TVH_ADAPTERS=
+#TVH_HTTP_PORT=9981
+#TVH_HTSP_PORT=9982
+#TVH_DEBUG=1
diff --git a/package/tvheadend/tvheadend.init b/package/tvheadend/tvheadend.init
new file mode 100644
index 0000000..b05ec81
--- /dev/null
+++ b/package/tvheadend/tvheadend.init
@@ -0,0 +1,54 @@ 
+#! /bin/sh
+# Startup script inspired by the one in the package
+
+# Author: Yann E. MORIN <yann.morin.1998@free.fr>
+
+PATH=/usr/sbin:/usr/bin:/sbin:/bin
+NAME=tvheadend
+DAEMON=/usr/bin/$NAME
+PIDFILE=/var/run/$NAME.pid
+
+[ -f "${DAEMON}" -a -x "${DAEMON}" ] || exit 0
+
+# Read configuration variable file if it is present
+[ -r "/etc/default/${NAME}" ] && . "/etc/default/${NAME}"
+
+ARGS="-f"
+[ -z "${TVH_USER}"      ] || ARGS="${ARGS} -u ${TVH_USER}"
+[ -z "${TVH_GROUP}"     ] || ARGS="${ARGS} -g ${TVH_GROUP}"
+[ -z "${TVH_ADAPTERS}"  ] || ARGS="${ARGS} -a ${TVH_ADAPTERS}"
+[ -z "${TVH_HTTP_PORT}" ] || ARGS="${ARGS} -w ${TVH_HTTP_PORT}"
+[ -z "${TVH_HTSP_PORT}" ] || ARGS="${ARGS} -e ${TVH_HTSP_PORT}"
+[ "${TVH_DEBUG}" = "1"  ] && ARGS="${ARGS} -s"
+
+case "$1" in
+    start)
+        printf "Starting TVHeadend daemon: "
+        if start-stop-daemon -S -q -p ${PIDFILE} -m --exec /usr/bin/tvheadend -- $ARGS; then
+            printf "OK\n"
+        else
+            printf "failed\n"
+        fi
+	    ;;
+    stop)
+        printf "Starting TVHeadend daemon: "
+        start-stop-daemon -K -q -p ${PIDFILE} -s TERM
+        sleep 2
+        if start-stop-daemon -K -q -p ${PIDFILE} -t; then
+            printf "failed, killing: "
+            start-stop-daemon -K -q -p ${PIDFILE} -s KILL -o
+        fi
+        printf "OK\n"
+    	;;
+    restart|force-reload)
+        "${0}" stop
+        sleep 2
+        "${0}" stop
+        ;;
+    *)
+        echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
+        exit 1
+        ;;
+esac
+
+:
diff --git a/package/tvheadend/tvheadend.mk b/package/tvheadend/tvheadend.mk
new file mode 100644
index 0000000..d2fe97a
--- /dev/null
+++ b/package/tvheadend/tvheadend.mk
@@ -0,0 +1,76 @@ 
+#############################################################
+#
+# tvheadend
+#
+##############################################################
+
+TVHEADEND_VERSION           = v3.3
+TVHEADEND_SITE              = http://github.com/tvheadend/tvheadend/tarball/$(TVHEADEND_VERSION)
+TVHEADEND_LICENSE           = GPLv3+
+TVHEADEND_LICENSE_FILES     = LICENSE
+TVHEADEND_DEPENDENCIES      = host-pkgconf openssl python
+
+ifeq ($(BR2_PACKAGE_AVAHI),y)
+TVHEADEND_DEPENDENCIES     += avahi
+endif
+
+#----------------------------------------------------------------------------
+# tvheadend is a little smuggler and thief! ;-)
+# During the ./configure, it downloads some files from the dvb-apps
+# package, so it has a list of pre-scanned tunner configurations.
+# For buildroot that has a few-unfortunate consequences:
+#  - the network may not be availabe at the time of build, if the
+#    user pre-downloaded the sources with 'make source'
+# So, here's what we do:
+#  - after the main archive download, we do download those files
+#  - after extract, we extract the required files
+
+TVHEADEND_DVBSCANS_VERSION  = 3fc7dfa68484
+TVHEADEND_DVBSCANS_SITE     = http://linuxtv.org/hg/dvb-apps/archive/
+TVHEADEND_DVBSCANS_DIR      = dvb-apps-$(TVHEADEND_DVBSCANS_VERSION)
+TVHEADEND_DVBSCANS_SOURCE   = $(TVHEADEND_DVBSCANS_DIR).tar.bz2
+
+define TVHEADEND_DOWNLOAD_DVBSCANS
+	$(call DOWNLOAD_WGET,$(TVHEADEND_DVBSCANS_SITE)/$(TVHEADEND_DVBSCANS_VERSION).tar.bz2,$(TVHEADEND_DVBSCANS_SOURCE))
+endef
+TVHEADEND_POST_DOWNLOAD_HOOKS        = TVHEADEND_DOWNLOAD_DVBSCANS
+
+define TVHEADEND_EXTRACT_DVBSCANS
+	mkdir -p $(@D)/data/dvb-scan
+	$(INFLATE.bz2) $(DL_DIR)/$(TVHEADEND_DVBSCANS_SOURCE)      |\
+	$(TAR) $(TAR_STRIP_COMPONENTS)=3 -C $(@D)/data/dvb-scan     \
+	       $(TAR_OPTIONS) -                                     \
+	       $(TVHEADEND_DVBSCANS_DIR)/util/scan/{atsc,dvb-{c,s,t}}
+endef
+TVHEADEND_POST_EXTRACT_HOOKS         = TVHEADEND_EXTRACT_DVBSCANS
+
+#----------------------------------------------------------------------------
+# To run tvheadend, we need:
+#  - a non-root user to be safe, with its owned ${HOME}
+#  - a startup script, and its config file
+#  - a default DB with a tvheadend admin
+TVHEADEND_MKUSER = TARGET_DIR=$(TARGET_DIR) INSTALL=$(INSTALL) package/tvheadend/tvheadend.mkuser
+define TVHEADEND_CREATE_USER
+	$(TVHEADEND_MKUSER) mk_user
+	$(INSTALL) -D package/tvheadend/tvheadend.config  $(TARGET_DIR)/home/tvheadend/.hts/tvheadend/accesscontrol/1
+endef
+TVHEADEND_POST_INSTALL_TARGET_HOOKS  = TVHEADEND_CREATE_USER
+
+define TVHEADEND_PERMISSIONS
+	/home/tvheadend                                d 0700 $$(shell $(TVHEADEND_MKUSER) get_uid) $$(shell $(TVHEADEND_MKUSER) get_gid) - - - - -
+	/home/tvheadend/.hts                           d 0700 $$(shell $(TVHEADEND_MKUSER) get_uid) $$(shell $(TVHEADEND_MKUSER) get_gid) - - - - -
+	/home/tvheadend/.hts/tvheadend                 d 0700 $$(shell $(TVHEADEND_MKUSER) get_uid) $$(shell $(TVHEADEND_MKUSER) get_gid) - - - - -
+	/home/tvheadend/.hts/tvheadend/accesscontrol   d 0700 $$(shell $(TVHEADEND_MKUSER) get_uid) $$(shell $(TVHEADEND_MKUSER) get_gid) - - - - -
+	/home/tvheadend/.hts/tvheadend/accesscontrol/1 f 0600 $$(shell $(TVHEADEND_MKUSER) get_uid) $$(shell $(TVHEADEND_MKUSER) get_gid) - - - - -
+endef
+
+define TVHEADEND_INSTALL_SYSV_STARTUP_FILES
+	$(INSTALL) -D package/tvheadend/tvheadend.default $(TARGET_DIR)/etc/default/tvheadend
+	$(INSTALL) -D package/tvheadend/tvheadend.init    $(TARGET_DIR)/etc/init.d/S99tvheadend
+endef
+TVHEADEND_INSTALL_INIT_SYSV          = TVHEADEND_INSTALL_SYSV_STARTUP_FILES
+
+#----------------------------------------------------------------------------
+# tvheadend is not an autotools-based package, but it is possible to
+# call its ./configure script as if it were an autotools one.
+$(eval $(autotools-package))
diff --git a/package/tvheadend/tvheadend.mkuser b/package/tvheadend/tvheadend.mkuser
new file mode 100755
index 0000000..558bc64
--- /dev/null
+++ b/package/tvheadend/tvheadend.mkuser
@@ -0,0 +1,52 @@ 
+#!/bin/sh
+set -e
+
+# Create the user that will be responsible for
+# running the tvheadend DVR daemon
+# If the user does not exist, create it and its home
+# If the user does exist, do nothing
+# Expected env variables:
+#   ${TARGET_DIR}   Base dir of the rootfs
+#   ${INSTALL}      our install program
+
+# Usage:
+# arg     | purpose
+# --------+----------------------------
+# mk_user | creates the user, see above
+# get_uid | prints the user's UID on stdout
+# get_gid | prints the user's GID on stdout
+
+PASSWD="${TARGET_DIR}/etc/passwd"
+GROUP="${TARGET_DIR}/etc/group"
+
+mk_user() {
+    # If the user exists, we assume the group does, too
+    if grep -E '^tvheadend:' "${TARGET_DIR}/etc/passwd" >/dev/null 2>&1; then
+        return 0
+    fi
+
+    prev_uid="$( cut -d: -f3 "${PASSWD}" |sort -n |tail -n1 )"
+    prev_gid="$( cut -d: -f3 "${GROUP}" |sort -n |tail -n1 )"
+
+    uid=$((prev_uid+1))
+    gid=$((prev_gid+1))
+
+    printf "tvheadend:x:%d:\n" ${gid} >>"${GROUP}"
+    printf "tvheadend:x:%d:%g:TVHeadend daemon:/home/tvheadend:/bin/false\n"    \
+           ${uid} ${gid}                                                        \
+           >>"${PASSWD}"
+    ${INSTALL} -d "${TARGET_DIR}/home/tvheadend"
+}
+
+get_uid() {
+    sed -r -e '/^tvheadend:[^:]*:([[:digit:]]+):.*/!d; s//\1/;' "${PASSWD}"
+}
+
+get_gid() {
+    sed -r -e '/^tvheadend:[^:]*:([[:digit:]]+):.*/!d; s//\1/;' "${GROUP}"
+}
+
+case "${1}" in
+    mk_user|get_uid|get_gid) ${1};;
+    *)                       exit 1;;
+esac