Multimedia Center "Kodi" and Yocto Project







Introduction to Yocto Project



Yocto Project is a collaborative Open Source project to simplify the development of distributions for embedded systems. Yocto contains a large number of templates, metadata, and build tools. In Yocto Project, you can connect a large number of BSP (platform support package) layers for all kinds of hardware platforms.



The main purpose of the article is an attempt to show the assembly of a typical distribution package in the Yocto Project using the example of the well-known multimedia center Kodi, version 17.6 for the Raspberry Pi 3B single-board computer.



If somewhere deep down in your soul you feel that you are a collector, but have not yet decided what you would like to collect, then this article is for you. If you already use the Yocto Project in your daily work, you can scroll through this article. Go straight to the last chapter and get ready.



The article is purely practical and demonstrates the possibility of using the achievements of the Yocto Project and OpenEmbedded for the assembly of the multimedia center "Kodi". Yocto layers are managed using the Repo utility from Google. An article from the Document this series.



So: let's go.



Content:



Install Yocto Project on Ubuntu

Distribution build engine in Yocto Project

Using OpenEmbedded with the Yocto Project

Platform Support Package (BSP)

Manage Yocto layers with Repo

Install Repo

Distribution Build Manifest

Manifesto Content

Manifest Description

Bs-manifest structure

Initializing Poky Variables

Repo Initialization

Repo Sync

Creating a Yocto Project Configuration

Configuration file build / conf / local.conf

Configuration file build / conf / bblayers.conf

Layer for assembling a multimedia center

Layer structure

Layer configuration

Composition recipes-berserk

Composition of recipes-core

Composition of recipes-kernel

Composition recipes-mediacentre

Composition of recipes-multimedia

Kodi Build Recipe Supplement

Adding a new item to the Kodi settings menu

Maximum buffering settings for video

Watching TV over IPTV

Watching Youtube with the Kodi Plugin

Console shell network configuration extension

Distribution Build Recipe

A brief guide to creating a distribution image

P.S



Install Yocto Project on Ubuntu



To build the distribution using the Yocto Project on Ubuntu, you need to install the following packages:



sudo apt-get install -y --no-install-suggests --no-install-recommends \ gawk wget git-core diffstat unzip texinfo gcc-multilib \ build-essential chrpath socat cpio python python3 python3-pip python3-pexpect \ xz-utils debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa libsdl1.2-dev \ xterm
      
      





Packages are installed using the apt-get install command and the privilege escalation command sudo . In the Ubuntu system, this is a widespread practice when the sudo command is used to perform administrative actions (when creating the main user of the system, it is automatically registered in the “sudo” group).



You can see more detailed installation instructions here:



Distribution build engine in Yocto Project



In the Yocto Project, each program unit is described using an assembly recipe. The recipe description language resembles “bash” with the ability to insert parts of the code in the python language. You can get basic syntax information from the Yocto Project manual . A set of assembly recipes, depending on the purpose, can be combined into separate assembly layers.



Layers are divided into hardware-dependent - BSP layers, UI layers (user interface), specific Yocto layers, as well as layers that implement certain functionality:

e.g. layers from OpenEmbedded => multimedia, python, perl, ruby, networking, systemd, webserver, etc.



Using OpenEmbedded with the Yocto Project



And yet, if you will use the Yocto Project, then for sure you will need layers with additional functionality i.e. A large set of recipes for all occasions. And there is such a set - these are recipes from OpenEmbedded. OpenEmbedded is an infrastructure for building packages for embedded Linux.



OpenEmbedded is fully compatible with the Yocto Project, as this project was taken as the basis for the Yocto Project. Perhaps that’s why the Yocto Project has slightly better stability, better documentation and slightly better support (but basically it's still the same OpenEmbedded).



Platform Support Package (BSP)



The Board Support Package is a separate, specialized layer (s) for a specific board that defines the hardware features of the platform i.e. implements those specific things that distinguish one board from another: processor features, interrupts, addressing, bootloader features, video adapter (GPU) features, etc.



This article uses the BSP layer - meta-raspberrypi

The layer repository is located at: git.yoctoproject.org/git/meta-raspberrypi



Manage Yocto layers with Repo



Yocto Project can use a large number of layers from different suppliers - equipment developers, and all this needs to be managed somehow. Imagine that you have a dozen different boards, and each board comes with a separate BSP git repository, and this is not counting the infrastructure of the Yocto project itself, plus possible additional functionality from OpenEmbedded.



In this situation, you won’t get away with a separate simple installation script. Willy-nilly, have to look for tools that can do it well. Even more than good. One of the best tools of this kind is the Google utility - Repo.



Repo is the main tool for managing GIT repositories when building the Android operating system with its large code base. Repo allows you to manage a dozen, if not a hundred separate git repositories in one project, versions of which you can carefully specify in one xml file of the Manifesto



and for proper synchronization of all versions of all repositories you just need to run one command



repo sync



Repo Installation



Using the following set of commands, you can install Repo in your ~ / bin home directory

(curl command can be installed separately: sudo apt-get install curl)



 PATH=${PATH}:~/bin mkdir ~/bin curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > ~/bin/repo chmod a+x ~/bin/repo
      
      







and in the future you just need to use the command in the console: repo



or so

if the HOME / bin directory is not added with the standard startup path automatically

see file HOME / .profile



$

$ PATH = $ {PATH}: ~ / bin

$ repo

$



Distribution Build Manifest



The distribution that is being assembled as part of the article, I need to call it something. Let it be the name Torvin . Codenamed Torvin, there will be a minimalist Linux distribution with the assembly of one single program. This means one application user program - Kodi, and nothing more (everything else is a system level). For a multimedia center, in my opinion this is quite enough.



Manifesto Content



The torvin-0.2.5.xml file is used to manage distribution layers .



  <?xml version="1.0" encoding="UTF-8"?> <manifest> <default sync-j="4" revision="rocko"/> <remote fetch="https://git.yoctoproject.org/git" name="yocto"/> <remote fetch="https://github.com/openembedded" name="oe"/> <remote fetch="https://github.com/berserktv" name="bs"/> <project remote="bs" revision="master" name="bs-manifest" path="sources/bs-manifest"> <linkfile dest="setup-environment" src="setup-environment"/> <linkfile dest="shell.sh" src="raspberry/shell.sh"/> <linkfile dest="sources/base" src="raspberry/rocko"/> </project> <project remote="yocto" revision="rocko" name="poky" path="sources/poky"/> <project remote="oe" revision="rocko" name="meta-openembedded" \ path="sources/meta-openembedded"/> <project remote="yocto" revision="rocko" name="meta-raspberrypi" \ path="sources/meta-raspberrypi"/> <project remote="bs" revision="rocko" name="berserk" path="sources/berserk"/> </manifest>
      
      





Manifest Description



At the beginning of the manifest, remote tags denote two main GIT repositories and one auxiliary:



https: ⁄⁄git.yoctoproject.org / git - Yocto repository named as yocto

https: ⁄⁄github.com / openembedded - OpenEmbedded repository named as oe

https: ⁄⁄github.com / berserktv - auxiliary GIT repository named as bs



In the next part of the manifest, using abbreviated naming, we work with projects located in these repositories, the project tag contains the following attributes:



remote - the name of the remote named repository

revision - name of the branch or hash version

name - name of the project in the specified repository

path - the local project path in your file system



    <project remote="bs" revision="master" name="bs-manifest" path="sources/bs-manifest"> </project>  xml      : git clone https://github.com/berserktv/bs-manifest -b master sources/bs-manifest
      
      





In the body of the project tag, I indicated commands for creating symbolic links to the infrastructure of auxiliary scripts for initialization and regular start of the Poky build system



    linkfile <project remote="bs" revision="master" name="bs-manifest" path="sources/bs-manifest"> <linkfile dest="setup-environment" src="setup-environment"> <linkfile dest="shell.sh" src="raspberry/shell.sh"> <linkfile dest="sources/base" src="raspberry/rocko"> </project>        : ln -s src dest .. #      ln -s sources/bs-manifest/setup-environment setup-environment ln -s sources/bs-manifest/raspberry/shell.sh shell.sh #    ,  #      cd sources ln -s bs-manifest/raspberry/rocko base
      
      





Bs-manifest structure



 ├── COPYING.MIT
 ├── raspberry
 │ ├── rocko
 │ │ ├── conf
 │ │ │ ├── bblayers.conf
 │ │ │ └── local.conf
 │ │ └── torvin-0.2.5.xml
 │ └── shell.sh
 ├── README.md
 └── setup-environment




The bs-manifest project is used for flexible configuration management, taking into account the assemblies of different versions of the distribution. I have this version - 0.2.5



Initializing Poky Variables



The setup-environment initialization script was taken from the Freescale Community project (in the yocto environment, this is a common solution). The script is responsible for the initialization of variables of the Poky build system, the script creates a directory structure in which it is very well divided:





The contents of the setup-environment script can be viewed here:



Shell.sh script contents
  #!/bin/bash MACHINE='raspberrypi3' source ./setup-environment build echo "you may try 'bitbake core-image-minimal'" bash
      
      







This root script serves to initialize the configuration variables of the build environment and is usually called at the beginning of a session.



Repo Initialization



To initialize repo, you must run the command:



 mkdir torvin cd torvin repo init -u https:⁄⁄github.com/berserktv/bs-manifest -m raspberry/rocko/torvin-0.2.5.xml
      
      





where -u https: ⁄⁄github.com / berserktv / bs-manifest tells GIT the path to the manifest project



note: you can also specify -b tree_name

(if you do not specify the -b switch, then the master branch is assumed (by default))



where the path -m raspberry / rocko / torvin-0.2.5.xml to the configuration file indicates the following:



  1. The name of the hardware platform for which the assembly is being performed - raspberry
  2. The name of the main Yocto / OpenEmbedded work branch is rocko
  3. The code name of the version is torvin (all versions of the 0.2.x series)
  4. The digital version number that is being assembled is 0.2.5


Repo Sync



for initial loading or subsequent synchronization, just run the command:



 repo sync
      
      





which will pick up all the latest versions of GIT projects specified in the manifest file (branches are usually indicated), if you have a hash commit or tag name in the revision attribute, then the version for this git repository will not change. The tag name can be specified like this: revision = "refs / tags / v0.2.5"



Creating a Yocto Project Configuration



After the repo sync command is executed, you can start creating the main configuration of the Yocto Project:



 ./shell.sh
      
      





after the script completes, the build / conf directory will be created:

with two main files:





by default, the setup-environment script looks for sources / base / conf

initial configuration and if local.conf and bblayers.conf files

exist, they are copied to build / conf

(see the TEMPLATES variable in setup-environment)



those. files are taken from sources / bs-manifest / raspberry / rocko / conf

see creating a symbolic link to base



Configuration file build / conf / local.conf



Show / Hide
  MACHINE ??= 'raspberrypi3' DISTRO ?= 'poky' PACKAGE_CLASSES ?= "package_deb" EXTRA_IMAGE_FEATURES ?= "debug-tweaks" USER_CLASSES ?= "buildstats image-mklibs image-prelink" PATCHRESOLVE = "noop" BB_DISKMON_DIRS = "\ STOPTASKS,${TMPDIR},1G,100K \ STOPTASKS,${DL_DIR},1G,100K \ STOPTASKS,${SSTATE_DIR},1G,100K \ STOPTASKS,/tmp,100M,100K \ ABORT,${TMPDIR},100M,1K \ ABORT,${DL_DIR},100M,1K \ ABORT,${SSTATE_DIR},100M,1K \ ABORT,/tmp,10M,1K" PACKAGECONFIG_append_pn-qemu-native = " sdl" PACKAGECONFIG_append_pn-nativesdk-qemu = " sdl" CONF_VERSION = "1" DL_DIR ?= "${BSPDIR}/downloads/" # size memory GPU for Raspberry Pi GPU_MEM = "128" GPU_MEM_256 = "112" GPU_MEM_512 = "160" GPU_MEM_1024 = "320" # for libs: "mpeg2dec libmad ffmpeg x264" LICENSE_FLAGS_WHITELIST += "commercial"
      
      







Configuration file build / conf / bblayers.conf



Show / Hide
  # POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf # changes incompatibly LCONF_VERSION = "6" POKY_BBLAYERS_CONF_VERSION = "2" BBPATH = "${TOPDIR}" BSPDIR := \ "${@os.path.abspath(os.path.dirname(d.getVar('FILE', True)) + '/../..')}" BBFILES ?= "" BBLAYERS ?= " \ ${BSPDIR}/sources/poky/meta \ ${BSPDIR}/sources/poky/meta-poky \ ${BSPDIR}/sources/poky/meta-yocto-bsp \ ${BSPDIR}/sources/meta-openembedded/meta-oe \ ${BSPDIR}/sources/meta-openembedded/meta-python \ ${BSPDIR}/sources/meta-openembedded/meta-networking \ ${BSPDIR}/sources/meta-openembedded/meta-multimedia \ ${BSPDIR}/sources/meta-openembedded/meta-filesystems \ ${BSPDIR}/sources/meta-raspberrypi \ ${BSPDIR}/sources/berserk/meta-berserk \ "
      
      









main variables of the local.conf file - which you need to pay attention to:





specific settings for the Raspberry Pi family of boards





note:

for example, if you leave only the variable GPU_MEM = "128",

then for all RPI, RPI2, RPI3 boards

regardless of the amount of real RAM

on the board will always be allocated for the GPU - 128Mb

(and the total RAM size decrease by this value)



if all variables are specified, the directives GPU_MEM_256, GPU_MEM_512, GPU_MEM_1024 are more priority.



For the assembly of the Multimedia Center, in addition to the regular Yocto layers, see the bblayers.conf file



 ${BSPDIR}/sources/poky/meta \ ${BSPDIR}/sources/poky/meta-poky \ ${BSPDIR}/sources/poky/meta-yocto-bsp \
      
      





I connected four layers with additional functionality from OpenEmbedded.



Kodi Multimedia Center - is a complex program that uses a large number of external libraries and each library needs to be assembled using the build recipe, so if possible I will use all recipes from OpenEmbedded in the Multimedia category



So, I have a Multimedia layer connected and the layers on which it depends



 ${BSPDIR}/sources/meta-openembedded/meta-oe \ ${BSPDIR}/sources/meta-openembedded/meta-python \ ${BSPDIR}/sources/meta-openembedded/meta-networking \ ${BSPDIR}/sources/meta-openembedded/meta-multimedia \
      
      





then another OpenEmbedded layer is connected to work with file systems



 ${BSPDIR}/sources/meta-openembedded/meta-filesystems \
      
      





further connected the main BSP layer for the Raspberry Pi platform



 ${BSPDIR}/sources/meta-raspberrypi \
      
      





Well, at the very end, an additional layer is connected, responsible for assembling the distribution image with the functionality of the "Multimedia Center"



 ${BSPDIR}/sources/berserk/meta-berserk \
      
      





Layer for assembling a multimedia center



In my opinion, the Yocto Project is an industrial combine for creating embedded distributions. But if you've ever worked with the Buildroot build system, then Yocto may seem cumbersome to you. It uses a huge amount of free hard disk space. For normal operation, Yocto requires about 80 - 100 GB of free space, and this is usually taking into account assembly only for one platform.



Yocto copes with its main purpose perfectly - supporting as many different hardware platforms as possible, and this requires the most flexible assembly switching mechanism. And this mechanism needs time and place. Building a distribution in Yocto is not a quick process.



So, all the functionality for building the "Multimedia Center" I have with a separate layer:



 https://github/berserktv/berserk
      
      





(Title taken from my favorite book, The Hammer and the Cross, by Harry Harrison.)

(Torvin is also a character in this book.)



To make the functionality I need, I will use the so-called add-ons for recipes, which are located in files with the extension .bbappend

in the .bbappend file, you can add your own command calls for the regular build recipe method, for example, to the do_configure, do_compile, do_install method, etc.



Layer structure



 ├── COPYING.MIT
 ├── meta-berserk
 │ ├── conf
 │ │ └── layer.conf
 │ ├── recipes-berserk
 │ │ ├── bs-net
 │ │ ├── first-run
 │ │ ├── images
 │ │ └── tv
 │ ├── recipes-core
 │ │ ├── init-ifupdown
 │ │ └── psplash
 │ ├── recipes-kernel
 │ │ └── linux
 │ ├── recipes-mediacentre
 │ │ ├── kodi
 │ │ └── kodi-plugins
 │ └── recipes-multimedia
 │ └── ffmpeg
 ├── README.md
 └── changelog.txt




Layer composition:





layer configuration



includes layer.conf file
  # We have a conf and classes directory, add to BBPATH BBPATH .= ":${LAYERDIR}" # We have a packages directory, add to BBFILES BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ ${LAYERDIR}/recipes-*/*/*.bbappend" BBFILE_COLLECTIONS += "bs" BBFILE_PATTERN_bs := "^${LAYERDIR}/" BBFILE_PRIORITY_bs = "5" DISTRO_FEATURES_append += " wifi x11" PREFERRED_VERSION_ffmpeg = "3.1.11" SYSVINIT_ENABLED_GETTYS = "1" PREFERRED_VERSION_linux-raspberrypi ?= "4.9%"
      
      







The file contains an indication of the version of the ffmpeg library, the version number of the linux kernel, as well as the number of virtual consoles (tty), and includes the features of the distribution kit - wifi x11

DISTRO_FEATURES_append + = "wifi x11"



PREFERRED_VERSION_ffmpeg = "3.1.11"

SYSVINIT_ENABLED_GETTYS = "1"



PREFERRED_VERSION_linux-raspberrypi? = "4.9%"



composition of recipes-berserk



 ├── bs-net
 │ └── bs-net_0.1.3.bb
 ├── first-run
 │ ├── files
 │ │ └── first-run.sh
 │ └── first-run.bb
 ├── images
 │ └── berserk-image.bb
 └── tv
     ├── files
     │ └── berserk.m3u8
     ├── tv-config.bb
     └── tv-dir.inc




Where:





recipes-core composition



 ├── init-ifupdown
 │ ├── files
 │ │ └── interfaces
 │ └── init-ifupdown_1.0.bbappend
 └── psplash
     ├── files
     │ └── psplash-berserk-img.h
     └── psplash_git.bbappend




Where:





The network configuration on the target device is in the file:



 /etc/network/interfaces
      
      





Having added the extension of the recipe init-ifupdown, I replace the regular configuration file with my own, and change the order (priority) of running the script for execution levels



 INITSCRIPT_PARAMS = "start 98 2 3 4 5 . stop 10 0 6 1 ."
      
      





At the moment, almost all modern Linux distributions include a startup screen. Usually, the startup screen saver shows the current download status i.e. indicator of time elapsed since the system started. In this regard, Yocto is no exception and you can change the image of the standard start-up screen saver to an arbitrary picture.



To do this, you must:



  1. FILESEXTRAPATHS_prepend - add directory for resources
  2. SRC_URI - add a header file with an arbitrary picture
  3. SPLASH_IMAGES - change package control variable


and further in the image recipe “berserk-image.bb” it is necessary to add the splash start-up image as the features of the image



 IMAGE_FEATURES += "splash" #          SPLASH = "psplash-berserk"
      
      





composition of recipes-kernel



 └── linux
     ├── files
     │ ├── db.txt.patch
     │ └── rbpi.cfg
     └── linux-raspberrypi_4.9.bbappend




Where:





Wi-Fi devices operate at certain frequencies and for them there is such a thing as a regulatory domain - this parameter specifies the country in which this device is supposed to work.



The Linux kernel has an accompanying database in which the permitted frequencies and the allowed power for them are registered for each country.



In the simplest case, this database can be directly included in the kernel statically by specifying a parameter:

CONFIG_CFG80211_INTERNAL_REGDB = y

which I actually did by connecting a patch with this db.txt.patch database



And one more thing: in Yocto there is such a thing as fragments of kernel configurations. Usually, a configuration fragment, a file with the cfg extension, contains only those kernel parameters that you clearly need for certain purposes. And this piece of configuration is added to the default parameters that are already present in the recipe when building the kernel.



In addition to the bbappend recipe, you can also change the parameters that are passed to the kernel during startup:



those. override variable

CMDLINE see linux-raspberrypi_4.9.bbappend file



rbpi.cfg content
  # use statically compiled regulatory rules database CONFIG_CFG80211_INTERNAL_REGDB=y #  Wifi  Asus USB-N53 chipset Ralink RT3572 CONFIG_RT2800USB=m #  wifi    Atheros D-Link DWA-126 802.11n (AR9271), # NetGear WNDA3200, NetGear WNA1100, TP-Link TL-WN722N (AR9271), # TL-WN322G v3, TL-WN422G  .. . cateee.net CONFIG_ATH9K_HW=m CONFIG_ATH9K_HTC=m #  Wifi    wpa_supplicant CONFIG_WIRELESS=y CONFIG_WEXT_CORE=y CONFIG_WEXT_PROC=y CONFIG_CRYPTO_AES=y #    IPSec,    Wifi  #   wpa_supplicant   CONFIG_CRYPTO_CCM=m CONFIG_CRYPTO_CTR=m CONFIG_CRYPTO_ARC4=m ######################### #   CONFIG_HAVE_PERF_EVENTS=y CONFIG_PERF_EVENTS=y CONFIG_HAVE_LATENCYTOP_SUPPORT=y CONFIG_LATENCYTOP=y # This option adds support for ASIX AX88xxx # based USB 2.0 10/100 Ethernet adapters. CONFIG_USB_NET_AX8817X=m
      
      







linux-raspberrypi_4.9.bbappend
  #      rpbi.cfg FILESEXTRAPATHS_prepend := "${THISDIR}/files:" SRC_URI += "file://db.txt.patch;patch=1 \ file://rbpi.cfg \ " #  BSP  meta-raspberrypi     # https://github.com/agherzan/meta-raspberrypi/issues/14 #    #   do_kernel_configme   #     arch/    do_kernel_configme_append() { cat ${WORKDIR}/rbpi.cfg >> ${WORKDIR}/defconfig } # CMDLINE for raspberrypi # default CMDLINE = "dwc_otg.lpm_enable=0 console=serial0,115200 # root=/dev/mmcblk0p2 rootfstype=ext4 rootwait" CMDLINE = "quiet dwc_otg.lpm_enable=0 console=serial0,115200 \ root=/dev/mmcblk0p2 rootfstype=ext4 rootwait"
      
      







recipes-mediacentre



 ├── kodi │  ├── kodi │  ├── kodi_17.bbappend │  ├── kodi-dir.inc │  ├── kodi-runner.bb │  ├── kodi-settings.bb │  └── kodi-version.inc └── kodi-plugins ├── files ├── kodi-language-ru_3.0.10.bb ├── kodi-pvr-iptvsimple.bb ├── plugin-video-youtube_5.5.1.bb ├── screensaver-kodi-universe_0.1.2.bb ├── script-berserk-network_0.2.5.bb └── script-module-requests_2.12.4.bb
      
      





Where:



  1. kodi/

    • kodi — icon,run,settings

    • kodi_17.bbappend — Kodi
    • kodi-dir.inc — Kodi
    • kodi-runner.bb — Kodi
    • kodi-settings.bb — Kodi
    • kodi-version.inc — Kodi


  2. kodi-plugins/



    • files — tar.gz
    • kodi-language-ru_3.0.10.bb — ( Kodi)
    • kodi-pvr-iptvsimple.bb — Kodi pvr-iptvsimple
    • plugin-video-youtube_5.5.1.bb — Kodi «Youtube»
    • screensaver-kodi-universe_0.1.2.bb — screensaver-kodi-universe
    • script-berserk-network_0.2.5.bb —
    • script-module-requests_2.12.4.bb — Youtube




recipes-multimedia



└── ffmpeg
    ├── ffmpeg
    │  ├── 0001-ffmpeg-Call-get_format-to-fix-an-issue-with-MMAL-ren.patch
    │  ├── h264_parser.patch
    │  └── pfcd_hevc_optimisations.patch
    └── ffmpeg_3.1.11.bb




Where:





FFmpeg - OpenSource library for encoding / decoding a huge number of video and audio formats. FFmpeg supports almost 400 codecs (ffmpeg -codecs)

and over 300 formats (ffmpeg -formats).



Kodi Build Recipe Addition



The OpenEmbedded layer has a regular recipe for building Kodi, but it is quite general, and I would like to get a slightly more stable and tested version for the Raspberry Pi platform.



Software developers have such a thing as a reverse port patch. The software is constantly updated, and each new version includes both new features and the correction of known errors. The reverse porting patch allows you to transfer some of the changes in the new version of the program to an older one, thereby making it more stable. But this is a very hard and painstaking work, which is always carried out by a large number of developers.



In the world of the OpenSource community, there are several well-known projects using Kodi, the best of which (in my opinion) is LibreElec (OpenElec). LibreElec has a good build for the Raspberry Pi platform. Here they have the best way to take a reverse port patch for Kodi. Thus, you can get rid of a huge number of problems without even learning about it.



The Kodi multimedia center is focused on playing the “Media” context, and in my opinion the most critical component is the combination of Kodi and FFmpeg, i.e. interaction of certain versions of these programs, other libraries can be left from the Yocto and OpenEmbedded layers.



For assembly, I took the stable version of Kodi 17.6 and version FFmpeg 3.1.11



Note:
   ,       ,      systemD.         (   (  )).  ,     LibreElec       : #!/bin/bash HASH_VER="934507d922fb011ce46c76566206f2f1f603360b" git clone https://github.com/LibreELEC/LibreELEC.tv.git libreelec cd libreelec git checkout ${HASH_VER}   Kodi,   : projects/RPi2/patches/kodi (. : kodi-001-backport.patch)    FFmpeg,   : packages/multimedia/ffmpeg/patches
      
      







The included version description file will be such kodi-version.inc



 FILESEXTRAPATHS_prepend := "${THISDIR}/kodi:" #  Krypton SRCREV = "a9a7a20071bfd759e72e7053cee92e6f5cfb5e48" PV = "17.6+gitr${SRCPV}"
      
      





The Yocto and OpenEmbedded branch that I am considering - rocko , contains Kodi version 17.3, and in order to upgrade to version 17.6, just add a small addition to the recipe - kodi_17.bbappend



 require kodi-version.inc #     (   17.3) SRC_URI_remove = "file://0013-FTPParse.cpp-use-std-string.patch" #  ,   systemd   SRC_URI_remove = "file://0004-handle-SIGTERM.patch" #      RPI   libreelec SRC_URI_append += "file://kodi-krypton-rpb-backports.patch" #  error adding symbols: DSO missing from command line SRC_URI_append += "file://vchostif.patch" MENU_ICON = "addons/skin.estuary/media/icons/settings" #       ( ) SRC_URI_append += "file://bs-menu.patch file://icon/bs-network.png" do_configure_prepend() { install -m 0644 ${WORKDIR}/icon/bs-network.png ${S}/${MENU_ICON} } #    kodi plugins RRECOMMENDS_${PN}_append = "\ python-xml python-misc python-db \ python-crypt python-threading python-math python-email \ python-io python-netserver python-urllib3 python-datetime" #     Raspberry Pi #  OPENGL    --enable-gles #  kodi     docs/README.linux => libxmu libxinerama # libxtst xdpyinfo #      DISTRO_FEATURES   "x11" #   kodi  RPI1  RPI2,3    --disable-x11 BS_RPI = " --disable-gl --enable-openmax --enable-player=omxplayer \ --with-platform=raspberry-pi --disable-x11" BS_RPI3 = " --disable-gl --enable-openmax --enable-player=omxplayer \ --with-platform=raspberry-pi2 --disable-x11" EXTRA_OECONF_append = "${@bb.utils.contains('MACHINE', 'raspberrypi', \ '${BS_RPI}', '', d)}" EXTRA_OECONF_append = "${@bb.utils.contains('MACHINE', 'raspberrypi2', \ '${BS_RPI3}', '', d)}" EXTRA_OECONF_append = "${@bb.utils.contains('MACHINE', 'raspberrypi3', \ '${BS_RPI3}', '', d)}" #       Kodi   #  ,  USB  microSDHC  ( ) EXTRA_OECONF_append = " --enable-optical-drive"
      
      





The build option "--enable-optical-drive" allows you to connect the convenient notification mechanism that Kodi uses when connecting an optical disk. In this case, the MediaManager module (a) (xbmc / storage / MediaManager.cpp) monitors the connection / disconnection of new disk partitions and displays a pop-up message about it.



udev example of connecting / disconnecting drives:



 ACTION=="add" SUBSYSTEM=="block" ENV{ID_FS_TYPE}=="vfat" \ KERNEL=="sd[az][0-9]" \ RUN+="/bin/mkdir -p /media/%k", \ RUN+="/bin/mount -o iocharset=utf8,noatime /dev/%k /media/%k" ACTION=="add" SUBSYSTEM=="block" ENV{ID_FS_TYPE}=="ntfs" \ KERNEL=="sd[az][0-9]" \ RUN+="/bin/mkdir -p /media/%k", \ RUN+="/usr/bin/ntfs-3g -o \ iocharset=utf8,noatime,windows_names /dev/%k /media/%k" ACTION=="add" SUBSYSTEM=="block" ENV{ID_FS_TYPE}=="ext2|ext3|ext4" \ KERNEL=="sd[az][0-9]" \ RUN+="/bin/mkdir -p /media/%k", \ RUN+="/bin/mount -o noatime /dev/%k /media/%k" ACTION=="remove" SUBSYSTEM=="block" KERNEL=="sd[az][0-9]" \ RUN+="/bin/umount /media/%k", RUN+="/bin/rmdir /media/%k"
      
      





 :  rmdir     ,       ( Linux    -  )       .
      
      





Adding a new item to the Kodi settings menu



In Kodi 17.6, xml configuration files are responsible for displaying menu items. To add one more item under the “Settings” menu, just adjust the file:

kodi / addons / skin.estuary / xml / Settings.xml



where skin.estuary is the default menu design theme, the item



description looks like this:



<item>
    <label> $ LOCALIZE [13279] </label>
    <onclick> RunAddon (script.berserk.network, butnetwork) </onclick>
    <icon> icons / settings / bs-network.png </icon>
</item>




Where:



label - name of the menu item

onclick - handling the event of pressing the menu button

(launching the plugin, with the first argument passing the string “butnetwork”)

icon - icon of the menu item (path to png image)



The above functionality, as well as connecting several additional Kodi plugins, is integrated with using the bs-menu.patch file



Show / Hide
  diff -Naur a/addons/skin.estuary/xml/Settings.xml b/addons/skin.estuary/xml/Settings.xml --- a/addons/skin.estuary/xml/Settings.xml 2018-02-01 18:17:45.000000000 +0300 +++ b/addons/skin.estuary/xml/Settings.xml 2018-03-08 12:06:50.000000000 +0300 @@ -134,6 +134,11 @@ <icon>icons/settings/interface.png</icon> </item> <item> + <label>$LOCALIZE[13279]</label> + <onclick>RunAddon(script.berserk.network,butnetwork)</onclick> + <icon>icons/settings/bs-network.png</icon> + </item> + <item> <label>$LOCALIZE[20077]</label> <onclick>ActivateWindow(SkinSettings)</onclick> <icon>icons/settings/skin.png</icon> diff -Naur a/system/addon-manifest.xml b/system/addon-manifest.xml --- a/system/addon-manifest.xml 2018-03-07 15:58:24.000000000 +0300 +++ b/system/addon-manifest.xml 2018-05-14 14:06:58.000000000 +0300 @@ -27,6 +27,7 @@ <addon>resource.uisounds.kodi</addon> <addon>screensaver.xbmc.builtin.black</addon> <addon>screensaver.xbmc.builtin.dim</addon> + <addon>screensaver.kodi.universe</addon> <addon>script.module.pil</addon> <addon>service.xbmc.versioncheck</addon> <addon>skin.estuary</addon> @@ -43,4 +44,8 @@ <addon>xbmc.python</addon> <addon>xbmc.webinterface</addon> <addon optional="true">peripheral.joystick</addon> + <addon>script.berserk.network</addon> + <addon>resource.language.ru_ru</addon> + <addon>script.module.requests</addon> + <addon>plugin.video.youtube</addon> </addons>
      
      







Maximum buffering settings for video



In the Kodi Multimedia Center, to maximize performance, you can specify the maximum buffering settings:



 <advancedsettings> <cache> <buffermode>1</buffermode> <memorysize>139460608</memorysize> <readfactor>20</readfactor> </cache> </advancedsettings>
      
      





buffermode = 1

- buffer requests for all file systems (including local)



readfactor

- adjusts the download speed based on the average video bitrate. So, for example, if you play a video with an average data transfer rate of 5 Mbit / s and set the buffer read ratio to 2.0, this will limit the download speed (and therefore the cache fill rate) to about 10 Mbit / s, thus:



readfactor = 20

removes the restriction on the download speed



memorysize = 139460608

- the buffer size is 133 MB, while using 133 * 3 RAM i.e. about 400 MB of RAM



Watching TV over IPTV



Kodi Media Center is a very powerful tool for viewing digital content.



The main function for which I collected the "Media Center" is the function of watching digital television using IPTV (Internet Protocol Television) ie television over the internet protocol. With this function you can watch digital television from your Internet provider.



This is the most modern and optimal option both in terms of image quality and in terms of additional features i.e. services provided. For example, television channels can be provided in the archive, in which the desired video recording is available for some time after the broadcast.



To support IPTV in Kodi, there are several plugin options, of which I settled on the pluginpvr.iptvsimple



To build the plugin, use the recipe:



    └── kodi-plugins
        └── kodi-pvr-iptvsimple.bb




The plug-in is connected / configured through:

Kodi main menu => “Add-ons” => “My add-ons” => “PVR clients” => “PVR IPTV Simple Client”



To check the operation of IPTV television as part of Kodi, I took several public news channels and added them to the list in m3u8 format, and also included the automatic launch of the plugin “pvr.iptvsimple” at the start of the media center.



Watching Youtube with the Kodi Plugin



The programmers who developed Kodi provided the flexibility to expand its functions. This is done so that any enthusiast, if desired, could add to Kodi what he really needs. And these plugins for Kodi are darkness. Well, you get the point. There are so many of them that it deserves a description in a separate article.



Plugins are installed very simply, just connect Kodi to the Internet and press a couple of buttons in the menu. You can read about it on any of the forums dedicated to Kodi. But the assembly, there is the assembly, and I will include one more plugin in the distribution kit as an example.



The most interesting and widespread plugin (ohm) for Kodi in my opinion is the Youtube view plugin. Kodi is a multimedia center, and Youtube is the largest repository of this very multimedia content, so the Youtube plug-in for Kodi is almost mandatory.



The plugin is written in python, and this is a regular plug-in mechanism, you do not need to compile anything, just copy the finished plug-in to the root directory with the plug-ins, and specify the plug-in name in the manifest xml file:

“system / addon-manifest.xml”



The plug-in is taken from of the official repository, and its source code is included in the archive:

recipes-mediacentre / kodi-plugins / files / plugin.video.youtube.tar.gz For the



location of the plug-in assembly recipe, see the chapter “recipes-mediacentre composition” above



Console shell network configuration extension



Since the distribution kit assembled within the framework of this article is a demo, the requirements for setting up “Network Interfaces” are minimal. I did not want to drag any heavy network manager for this, which was very incomprehensible to me and very cumbersome, and therefore I wrote two shell scripts that complement the configuration of the regular configuration mechanism:



 ############################################################## #     /etc/network/interfaces: ############################################################## auto eth0 iface eth0 inet manual up /etc/network/eth-manual $IFACE up down /etc/network/eth-manual $IFACE down auto wlan0 iface wlan0 inet manual up /etc/network/wlan $IFACE up down /etc/network/wlan $IFACE down
      
      





To conveniently configure Ethernet / WLAN network interfaces via the GUI, I use another small Kodi plugin “script.berserk.network”. This is almost the only Kodi plugin I figured out, but for this I had to write it. It is extremely compact and minimalistic and written in the python language.



Both of these components are collected using recipes:





At this point, I would like to dwell on the details. So all the flexibility of using Yocto lies in different sets of recipes i.e. connected one set of recipes - the simplest network manager was added to the distribution kit, connected another set - added your favorite network manager using for example systemD, etc.



To automatically connect to a WiFi access point when the system starts, I use the udev rule: /etc/udev/rules.d/80-wifi-start.rules



 SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", KERNEL=="wlan*", \ RUN+="/etc/network/wlan-runner $env{INTERFACE} up" SUBSYSTEM=="net", ACTION=="remove", DRIVERS=="?*", KERNEL=="wlan*", \ RUN+="/etc/network/wlan-runner $env{INTERFACE} down"
      
      





The wlan-runner script simply executes the commands:

/ etc / network / wlan $ IFACE up

or

/ etc / network / wlan $ IFACE down



Distribution Build Recipe



The Yocto Project has a reuse mechanism. There are classes from which you can inherit (directive "inherit"), and there are basic recipes that you can connect (directive "include").



I will show inheritance using the class example:

poky / meta / clasess / core-image.bbclass



The class is responsible for describing the groups of packages that you can include in a particular recipe. To do this, it is enough to indicate the construction at the beginning of the recipe:

inherit core-image



Even in the text of this class you can see the features of the image, each feature is responsible for a group of functions included in the image, and each group ultimately describes a set of installed programs or libraries.



Features of the image are indicated as follows:



 IMAGE_FEATURES += "ssh-server-dropbear splash"
      
      





There is also DISTRO_FEATURES - distribution features that can be specified in the layer configuration file. These are distribution level functions, and if for example you change some feature (for example x11), then the subsequent assembly will begin to reassemble all packages that depend on this option (this can take quite a long time).



The basic basic recipe that I use:

poky / meta / recipes-core / images / core-image-minimal.bb



image build recipe
  # Project: "Berserk" - build Kodi for the Raspberry Pi platform # license - The MIT License (MIT) DESCRIPTION = "Berserk - the image for the Raspberry PI" LICENSE = "MIT" MD5_SUM = "md5=0835ade698e0bcf8506ecda2f7b4f302" LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;${MD5_SUM}" IMAGE_FEATURES += "ssh-server-dropbear splash" #    rootfs    (250000kB=~250Mb) IMAGE_ROOTFS_EXTRA_SPACE_append += "+ 250000" # Base this image on core-image-minimal include recipes-core/images/core-image-minimal.bb # Set default password for 'root' user inherit extrausers ROOTUSERNAME = "root" ROOTPASSWORD = "berserk" EXTRA_USERS_PARAMS = "usermod -P ${ROOTPASSWORD} ${ROOTUSERNAME};" #  ,      SPLASH = "psplash-berserk" BS_DEBUG_TOOLS = "ldd strace ltrace" BS_GLIBC = "glibc-thread-db \ glibc-gconv-utf-16 \ glibc-gconv-utf-32 \ glibc-binary-localedata-en-us \ glibc-binary-localedata-ru-ru \ glibc-charmap-utf-8 \ " BS_BASE = "kernel-modules \ lsb \ pciutils \ parted \ tzdata \ dosfstools \ ntp \ ntpdate \ e2fsprogs-resize2fs \ ntfs-3g \ ntfsprogs \ " BS_WLAN = "kernel-module-rt2800usb \ kernel-module-rt2800lib \ kernel-module-rt2x00lib \ kernel-module-rt2x00usb \ kernel-module-cfg80211 \ kernel-module-nls-utf8 \ kernel-module-ath9k-common \ kernel-module-ath9k-hw \ kernel-module-ath9k-htc \ kernel-module-ctr \ kernel-module-ccm \ kernel-module-arc4 \ " BS_WIFI_SUPPORT = " \ iw \ dhcp-client \ wireless-tools \ wpa-supplicant \ linux-firmware \ " BS_SOFT = "mc \ kodi \ kodi-runner \ kodi-settings \ kodi-language-ru \ kodi-pvr-iptvsimple \ bs-net \ tv-config \ first-run \ script-berserk-network \ screensaver-kodi-universe \ plugin-video-youtube \ script-module-requests \ " # Include modules in rootfs IMAGE_INSTALL += " \ ${BS_BASE} \ ${BS_WLAN} \ ${BS_WIFI_SUPPORT} \ ${BS_GLIBC} \ ${BS_SOFT} \ ${BS_DEBUG_TOOLS} \ "
      
      









I would like to clarify that, for example , the kernel-modules package will install

all kernel modules specified in the defconfig file into the distribution image.



But if you strongly customize something, then of course you may not even need all the kernel modules, in which case it’s convenient to add each module by name, as indicated in the BS_WLAN variable , this is like a cheat sheet, specify only what you need and after checking the package "Kernel-modules" remove, check, etc.



A brief guide to creating a distribution image



1) Install the Yocto Project dependencies in Ubuntu:
  sudo apt-get install -y --no-install-suggests --no-install-recommends \ gawk wget git-core diffstat unzip texinfo gcc-multilib build-essential \ chrpath socat cpio python python3 python3-pip python3-pexpect \ xz-utils debianutils iputils-ping python3-git python3-jinja2 \ libegl1-mesa libsdl1.2-dev xterm
      
      







2) Download and install Repo:
  mkdir ~/bin curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > ~/bin/repo chmod a+x ~/bin/repo
      
      







3) Download the project from github:
  PATH=${PATH}:~/bin mkdir torvin cd torvin repo init -u https://github.com/berserktv/bs-manifest \ -m raspberry/rocko/torvin-0.2.5.xml repo sync
      
      







4) Build the project:
  ./shell.sh bitbake berserk-image
      
      







5) Write the distribution image to the memory card:


torvin/build/tmp/deploy/images/raspberrypi3





:

berserk-image-raspberrypi3.rpi-sdimg



c

c UTC



dd



:

«microSDHC»

.



$ sudo bash

$ cd torvin/build/tmp/deploy/images/raspberrypi3

$ dd if=berserk-image-raspberrypi3.rpi-sdimg of=/dev/sdX bs=1M

$ sync



/dev/sdX:

X a,b,c ..





:

Windows,

Win32 Disk Imager :

:





Note:
              N      ,      ""          ,    git  (..         "")   :  - Intel(R) Core(TM) i5-3570 CPU @ 3.40GHz  - 8    -  USB-3.0 1T   - 4  05    - 1     - 274.8 M   torvin/build    (cache ,   ,   ,  ,   ,    ..) -   42    torvin/downloads -  9.1  (git    tar.gz )  rootfs   - 550     /lib/firmware - 212  /lib/modules - 53  :        firmware (   )       ,   200 
      
      







P.S



The capabilities of OpenSource in recent years are only increasing.



But these opportunities are not small, for examples you do not even have to go far. It is unlikely that the same "Microsoft" expected that OpenSource technology will throw it from the market of mobile operating systems. I mean the OS from Google - "Android", which overnight threw the "Pioneer" of mobile systems on the sidelines. And it is not clear whether Microsoft will be able to return to it again.



Of course, "Google", a huge corporation with almost unlimited finances and excellent developers, but still, as they say "without the Core and not here and there."



Best OpenSource projects over time become a work of art (e.g. Kodi, Openelec / libre, etc.)



And today, anyone can join the best practices in OpenSource, so to speak, without crawling out of Github (a). This article is about it.



Have a lot of good and different assemblies for you, and remember "the world of the Internet of things is coming."



All Articles