Intégrer les Google Apps à la compilation d’une rom Android

Ce post décrit une méthode permettant d’inclure les Google Apps directement dans une rom Android.
Cela évite ainsi de devoir flasher l’appareil 2 fois de suite à chaque mise à jour de la ROM : une fois pour la rom elle-même, puis une seconde fois avec les Google Apps.

Ce post ne décrit pas comment compiler une ROM, il suppose que l’environnement est déjà en place et fonctionne !
L’intégration des Google Apps n’est clairement pas autorisée par Google dans le cadre d’une distribution publique de la ROM. La méthode n’est donc à faire que pour vos propres compilation et rien d’autre.

  1. La première chose à faire est évidemment de se procurer les Google Apps. Vous pouvez les trouver ici.
  2. Ensuite ouvrez un shell et sourcez le fichier ~/buid/envsetup.sh : source ${VOTRE_RACINE_ANDROID}/build/envsetup.sh
  3. Décompressez les Google Apps dans le dossier suivant $ANDROID_BUILD_TOP/vendor/extra/google. Créez le dossier s’il n’existe pas. Pour préciser, vous devriez avoir un fichier $ANDROID_BUILD_TOP/vendor/extra/google/install-optional.sh  après décompression
  4. Exécutez le script ci-dessous dans ce même shell
  5. Ouvrez le fichier $ANDROID_BUILD_TOP/vendor/asus/tf700t/tf700t-vendor.mk  (remplacez évidemment ce qu’il faut pour votre apareil) et ajoutez-y $(call inherit-product-if-exists, vendor/extra/google.mk)
  6. Plus qu’à lancer une compilation
#!/bin/bash
FOUT=$ANDROID_BUILD_TOP/vendor/extra/google.mk

cd $ANDROID_BUILD_TOP/vendor/extra/google
echo 'PRODUCT_COPY_FILES += \' > $FOUT
find system -type f -exec echo -e \\tvendor/extra/google/\{\}:/\{\} \\ \; | sort >> $FOUT
echo 'PRODUCT_COPY_FILES += \' >> $FOUT
find optional -type f -exec echo -e \\tvendor/extra/google/\{\}:/\{\} \\ \; | sort >> $FOUT

 

ERRATA: il faut enlever les 2 \ finaux qui trainent dans le fichier généré.

Purger massivement des MKV

J’ai écrit un petit script en Powershell afin de pouvoir traiter en masse des fichiers MKV en y enlevant toutes les pistes qui ne m’intéressaient pas.
Les MKV ont en effet la capacité d’embarquer plusieurs flux vidéos, audios, sous-titres et même des fichiers joints (des polices embarquées par exemple pour une utilisation avec les sous-titres), ce qui est très pratique.
Dans mon cas, il s’agissait de vidéos avec 3 flux audios, 3 sous-titres dont les 2/3 en russe (que je ne parle pas), le dernier tiers en anglais.

Afin d’alléger les fichiers et ainsi pouvoir les visionner sur mon téléphone, j’ai cherché le moyen de pouvoir effectuer cette purge, mais rapidement. Pour cela, les MKVToolnix, la boite à outil officielle du conteneur MKV vont être très utiles, ils contiennent :

  • un outil permettant d’analyser un MKV et donc de voir ce qu’il contient
  • un outil d’extraction
  • et enfin un outil de « création »

Le script en question est donc surtout un « parser » pour mkvinfo, l’outil d’analyse, permettant ensuite de lancer tout seul la suite des opérations.

Voici la sorti type d’un mkvinfo

+ En-tête EBML
|+ Type de document : matroska
|+ Version du type de document : 2
|+ Version lue du type de document : 2
+ Segment, taille 2409578102
|+ En-tête de recherche (sous-entrées ignorées)
|+ EbmlVoid (taille : 4012)
|+ Informations sur le segment
| + Coefficient temporel : 1000000
| + Application de multiplexage : libebml v0.7.9 + libmatroska v0.8.1
| + Application d'écriture : mkvmerge v3.2.0 ('Beginnings') built on Feb 12 2010 16:46:17
| + Durée : 3479.872s (00:57:59.872)
| + Date : Mon Mar 01 18:00:07 2010 UTC
| + Titre : Alpha News 1x01
| + UID de segment : 0x9b 0xe4 0xc8 0x25 0x73 0x3d 0xb7 0xed 0x81 0xc7 0x25 0x6e 0xb9 0x36 0x9e 0x8e
|+ Pistes du segment
| + Une piste
| + Numéro de piste : 1 (identifiant de piste pour mkvmerge & mkvextract : 0)
| + UID de piste : 323836576
| + Type de piste : video
| + Activé : 1
| + Marque par défaut : 1
| + Marque de forçage : 0
| + Marque de laçage : 0
| + Cache minimum : 1
| + Coefficient temporel : 1
| + Identifiant d'ajout de bloc maximum : 0
| + Identifiant du codec : V_MPEG4/ISO/AVC
| + Codec de décodage intégral : 1
| + Données de codec privées, longueur 95 (profil h.264 : High @L3.1)
| + Durée par défaut : 41.708ms (23.976 images/champs par seconde pour une piste vidéo)
| + Langue : eng
| + Nom : "Pilot"
| + Piste vidéo
| + Largeur (pixels) : 1280
| + Hauteur (pixels) : 720
| + Entrelacé : 0
| + Largeur à l'écran : 1280
| + Hauteur à l'écran : 720
| + Une piste
| + Numéro de piste : 2 (identifiant de piste pour mkvmerge & mkvextract : 1)
| + UID de piste : 3094425017
| + Type de piste : audio
| + Activé : 1
| + Marque par défaut : 1
| + Marque de forçage : 0
| + Marque de laçage : 1
| + Cache minimum : 0
| + Coefficient temporel : 1
| + Identifiant d'ajout de bloc maximum : 0
| + Identifiant du codec : A_AC3
| + Codec de décodage intégral : 1
| + Durée par défaut : 32.000ms (31.250 images/champs par seconde pour une piste vidéo)
| + Langue : rus
| + Nom : Dolby Digital 5.1 448 kbps @ Lostfilm
| + Audio track
| + Fréquence d'échantillonnage : 48000
| + Canaux : 6
| + Une piste
| + Numéro de piste : 3 (identifiant de piste pour mkvmerge & mkvextract : 2)
| + UID de piste : 31873723
| + Type de piste : audio
| + Activé : 1
| + Marque par défaut : 0
| + Marque de forçage : 0
| + Marque de laçage : 1
| + Cache minimum : 0
| + Coefficient temporel : 1
| + Identifiant d'ajout de bloc maximum : 0
| + Identifiant du codec : A_AC3
| + Codec de décodage intégral : 1
| + Durée par défaut : 32.000ms (31.250 images/champs par seconde pour une piste vidéo)
| + Langue : rus
| + Nom : Dolby Digital 5.1 448 kbps @ foxlight
| + Audio track
| + Fréquence d'échantillonnage : 48000
| + Canaux : 6
| + Une piste
| + Numéro de piste : 4 (identifiant de piste pour mkvmerge & mkvextract : 3)
| + UID de piste : 3654252222
| + Type de piste : audio
| + Activé : 1
| + Marque par défaut : 0
| + Marque de forçage : 0
| + Marque de laçage : 1
| + Cache minimum : 0
| + Coefficient temporel : 1
| + Identifiant d'ajout de bloc maximum : 0
| + Identifiant du codec : A_AC3
| + Codec de décodage intégral : 1
| + Durée par défaut : 32.000ms (31.250 images/champs par seconde pour une piste vidéo)
| + Langue : eng
| + Nom : Dolby Digital 5.1 448 kbps
| + Audio track
| + Fréquence d'échantillonnage : 48000
| + Canaux : 6
| + Une piste
| + Numéro de piste : 5 (identifiant de piste pour mkvmerge & mkvextract : 4)
| + UID de piste : 152612246
| + Type de piste : subtitles
| + Activé : 1
| + Marque par défaut : 0
| + Marque de forçage : 0
| + Marque de laçage : 0
| + Cache minimum : 0
| + Coefficient temporel : 1
| + Identifiant d'ajout de bloc maximum : 0
| + Identifiant du codec : S_TEXT/ASS
| + Codec de décodage intégral : 1
| + Données de codec privées, longueur 1555
| + Langue : rus
| + Nom : Russian @ ASS @ Faker020285
| + Une piste
| + Numéro de piste : 6 (identifiant de piste pour mkvmerge & mkvextract : 5)
| + UID de piste : 2319477894
| + Type de piste : subtitles
| + Activé : 1
| + Marque par défaut : 0
| + Marque de forçage : 0
| + Marque de laçage : 0
| + Cache minimum : 0
| + Coefficient temporel : 1
| + Identifiant d'ajout de bloc maximum : 0
| + Identifiant du codec : S_TEXT/ASS
| + Codec de décodage intégral : 1
| + Données de codec privées, longueur 1166
| + Langue : eng
| + Nom : English @ ASS
|+ EbmlVoid (taille : 1024)
|+ Pièces jointes
| + Joints
| + Nom du fichier : corbel_0.ttf
| + Type MIME : application/x-truetype-font
| + Données du fichier, taille : 260648
| + UIF du fichier : 4097748661
| + Description du fichier : Imported font from Breaking Bad 1x01 Pilot HD720p.ass
| + Joints
| + Nom du fichier : GARA_0.ttf
| + Type MIME : application/x-truetype-font
| + Données du fichier, taille : 198069
| + UIF du fichier : 1642350759
| + Description du fichier : Imported font from Breaking Bad 1x01 Pilot HD720p.ass
| + Joints
| + Nom du fichier : Candara_0.ttf
| + Type MIME : application/x-truetype-font
| + Données du fichier, taille : 218504
| + UIF du fichier : 3442251435
| + Description du fichier : Imported font from Breaking Bad 1x01 Pilot HD720p.ass
| + Joints
| + Nom du fichier : HermesCTT Regular_0.ttf
| + Type MIME : application/x-truetype-font
| + Données du fichier, taille : 54693
| + UIF du fichier : 2891661193
| + Description du fichier : Imported font from Breaking Bad 1x01 Pilot HD720p.ass
| + Joints
| + Nom du fichier : GOTHIC_0.ttf
| + Type MIME : application/x-truetype-font
| + Données du fichier, taille : 137565
| + UIF du fichier : 61850035
| + Description du fichier : Imported font from Breaking Bad 1x01 Pilot HD720p.ass
|+ Cluster

Cela va être très pratique à parser, les informations d’un même élément étant étalés sur plusieurs lignes.
L’idée va être de rassembler toutes les informations intéressantes dans un tableau avec :
* en première colonne, le numéro de piste pour mkvextract
* en seconde colonne, le type de la piste
* en troisième colonne, la langue de la piste

A coup de regex, cela donne quelque chose dans le style :

Piste Type Lang File 
----- ---- ---- ---- 
0 
video 
eng 
1 
audio 
rus 
2 
audio 
rus 
3 
audio 
eng 
4 
subtitles 
rus 
5 
subtitles 
eng 
corbel_0.ttf 
GARA_0.ttf 
Candara_0.ttf 
HermesCTT Regula...
GOTHIC_0.ttf

On retrouve bien le fait que l’information est éparpillée : pour chaque piste, l’information doit être lu sur 3 colonnes, mais à partir de ces informations, cela est suffisant pour lancer la commande de purge, on a donc tous les éléments en main pour écrire le script, ci-dessous.

function TransformMKV ($file) {
	$mkvinfo = 'C:\Program Files\MKVToolNix\mkvinfo.exe'
	$mkvextract = 'C:\Program Files\MKVToolNix\mkvextract.exe'
	$mkvmerge = 'C:\Program Files\MKVToolNix\mkvmerge.exe'
	$workdir = 'D:\temps'

	$rawOutput = & $mkvinfo $file
	$output = $rawOutput | Select-String -Pattern 'mkvextract : (?<piste>[0-9]+)', `
		'Type de piste : (?<type>.+)', `
		'Langue : (?<lang>.+)', `
		'Nom du fichier : (?<file>.+)'

	$data = $output | Select-Object @{"Label"="Piste";"Expression"={$_.Matches[0].Groups['piste'].Value}}, `
		@{"Label"="Type";"Expression"={$_.Matches[0].Groups['type'].Value}}, `
		@{"Label"="Lang";"Expression"={$_.Matches[0].Groups['lang'].Value}}, `
		@{"Label"="File";"Expression"={$_.Matches[0].Groups['file'].Value}}

	$i = 0
	$audioTracks = @()
	$subTracks = @()

	if ((Test-Path $workdir -PathType Container) -ne $true) {
		New-Item $workdir -ItemType folder
	}

	while ($i -lt $data.Count) {
		$line = $data[$i]
		$piste = $line.piste

		if ($piste -ne $null -and $piste -ne '') {
			$type = $data[++$i].type
			$lang = $data[++$i].lang

			if ($lang -eq 'rus') { continue }
			if ($type -eq 'subtitles') { $subTracks += $piste }
			elseif ($type -eq 'audio') { $audioTracks += $piste }
		}

		$i++
	}

	& $mkvmerge -q -o ("{0}\{1}" -f $workdir, [System.IO.Path]::GetFileName($file)) --default-language eng -a ($audioTracks -join ',') -s ($subTracks -join ',') "$file"
}

Get-Item -Path 'W:\source\*.mkv' | ForEach-Object { TransformMKV($_) }

 

C’est écrit à l’arrache, mais pour ce qui me concerne, il a été suffisant et reste simple à modifier.
On commence par indiquer en dur où se trouve les différents binaires, ainsi qu’un dossier de travail qui sera crée automatiquement s’il n’existe pas.
On balance un mkvinfo sur le fichier source qu’on transforme en object avec la cmdlet Select-Object . Il ne faut surtout pas utiliser Format-Table, lequel ne sert qu’à faire de l’affichage, et ne peut donc être pipé que dans la Console.

Durant la boucle, on rassemble les morceaux et on liste l’ensemble des pistes à garder (j’ai posé en hypothèse que je n’ai qu’une seule piste vidéo, et que donc je garde toutes les pistes vidéos lors de la purge).

Enfin on exécute mkvmerge, lequel a la capacité de créer des mkv à partir de flux nu, mais également à partir d’autres container, comme un mkv. La première solution étant plus difficile (car alors il faut également gérer l’existence et l’extraction des tags, chapitres, fichiers embarqués), je me suis tourné var la seconde solution, où il suffit d’indiquer ce que l’on souhaite garder et le reste est conservé.
La ligne de commande indique donc de garder tous les flux vidéos, tous les tags, chapitres et fichier embarqués, et de ne conserver que les flux audios et sous-titres spécifiés.

Enjoy !