ajout du patch ffmpeg + fix path

This commit is contained in:
Quentin Gibeaux 2019-01-16 12:21:51 +01:00 committed by Quentin Gibeaux
parent 92bd89bdbf
commit d0b2e52ee3
9 changed files with 392 additions and 0 deletions

View File

@ -0,0 +1,69 @@
From 1b016179fc18059382f8e047552e7031855764a0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= <revol@free.fr>
Date: Wed, 7 Nov 2018 14:31:04 +0100
Subject: [PATCH] libavformat/ffmetadec: use dynamic allocation for line buffer
When adding thumbnails to OGG files, the line can easily go up to 100kB.
We thus try to allocate the file size or SIZE_MAX to avoid truncation.
---
libavformat/ffmetadec.c | 21 +++++++++++++++++----
1 file changed, 17 insertions(+), 4 deletions(-)
diff --git a/libavformat/ffmetadec.c b/libavformat/ffmetadec.c
index 3290b3b7bc..ccbff51c03 100644
--- a/libavformat/ffmetadec.c
+++ b/libavformat/ffmetadec.c
@@ -128,16 +128,26 @@ static int read_tag(const uint8_t *line, AVDictionary **m)
static int read_header(AVFormatContext *s)
{
AVDictionary **m = &s->metadata;
- uint8_t line[1024];
+ int64_t line_size = avio_size(s->pb);
+ uint8_t *line;
+
+ if (line_size < 1 || line_size > SIZE_MAX)
+ line_size = SIZE_MAX;
+
+ line = av_malloc(line_size);
+ if (!line)
+ return AVERROR(ENOMEM);
while(!avio_feof(s->pb)) {
- get_line(s->pb, line, sizeof(line));
+ get_line(s->pb, line, line_size);
if (!memcmp(line, ID_STREAM, strlen(ID_STREAM))) {
AVStream *st = avformat_new_stream(s, NULL);
- if (!st)
+ if (!st) {
+ av_free(line);
return AVERROR(ENOMEM);
+ }
st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
st->codecpar->codec_id = AV_CODEC_ID_FFMETADATA;
@@ -146,8 +156,10 @@ static int read_header(AVFormatContext *s)
} else if (!memcmp(line, ID_CHAPTER, strlen(ID_CHAPTER))) {
AVChapter *ch = read_chapter(s);
- if (!ch)
+ if (!ch) {
+ av_free(line);
return AVERROR(ENOMEM);
+ }
m = &ch->metadata;
} else
@@ -160,6 +172,7 @@ static int read_header(AVFormatContext *s)
s->chapters[s->nb_chapters - 1]->time_base,
AV_TIME_BASE_Q);
+ av_free(line);
return 0;
}
--
2.19.1

25
ffmpeg-patch/README Normal file
View File

@ -0,0 +1,25 @@
Pour le traitement des podcasts, il est utile d'avoir un ffmpeg patché (du moins tant que le patch n'a pas été intégré dans la version officielle). C'est mmu_man (François Revol qui a fait le patch). Il permet d'ajouter par un script l'image de cover à nos podcasts sans que l'image soit floue. Sinon, il faut utiliser un logiciel avec un interface graphique, par exemple Easytag.
J'ai mis en ligne le tarball du FFmpeg que j'avais patché et compilé en novembre 2017 :
media.april.org/audio/radio-cause-commune/libre-a-vous/FFmpeg.tgz
Car visiblement le patch ne s'applique plus :
sudo apt install yasm
git clone https://github.com/FFmpeg/FFmpeg.git
cd FFmpeg
cd libavformat
git checkout d96ae9d5ea1f47a437fc0663b0cc26ff5d4d5d31
#pour être dans la version patchable
appliquer le patch:
patch < path/to/0001-libavformat-ffmetadec-use-dynamic-allocation-for-lin.patch
./configure
make

49
podcasts/README Normal file
View File

@ -0,0 +1,49 @@
Comment découper l'enregistrement en podcasts :
* Se positionner dans le dossier contenant l'enregistrement, les images, etc :
root@raspberrypi:~/lav-outils# ls -l ~/libreavous/
total 357004
drwxr-xr-x 19 root root 4096 janv. 7 11:47 FFmpeg
drwxr-xr-x 5 root root 4096 janv. 16 11:53 lav-outils
-rw-r--r-- 1 root root 99183 janv. 7 15:55 image-pour-etiqueter-podcast.jpg
-rw-r--r-- 1 root root 90081558 janv. 15 17:54 libre-a-vous-20190108.ogg
* Regarder le programme de l'émission et chercher les timestamp de début et de fin des différents podcast
* Décider d'un nom court, qui sera utilisé pour le fichier de podcast
* Écrire la conf json en s'inspirant de example.json (mettre à jour la date), par exemple :
{
"short_date" : "20190108",
"long_date" : "8 janvier 2019",
"ffmpeg_bin" : "./FFmpeg/ffmpeg",
"chapters" : [
{
"start_timestamp" : "0:03:09",
"end_timestamp" : "0:18:45",
"short_chapter_name" : "chronique-transcriptions"
},
{
"start_timestamp" : "00:18:45",
"end_timestamp" : "01:11:01",
"short_chapter_name" : "dinsic-etalab"
},
{
"start_timestamp" : "01:11:01",
"end_timestamp" : "01:23:38",
"short_chapter_name" : "logiciel-caisse"
},
{
"start_timestamp" : "01:23:38",
"end_timestamp" : "01:29:58",
"short_chapter_name" : "annonces"
}
]
}
* Exécuter le script :
root@raspberrypi:~/libreavous# lav-outils/scripts/make-all-podcasts.pl --config lav-outils/config/lav-20190115.json
* Les podcasts se retrouvent dans le dossier courant

View File

@ -0,0 +1,12 @@
{
"short_date" : "AAAAMMDD",
"long_date" : "DD MMMM AAAA",
"ffmpeg_bin" : "./FFmpeg/ffmpeg",
"chapters" : [
{
"start_timestamp" : "HH:MM:SS",
"end_timestamp" : "HH:MM:SS",
"short_chapter_name" : ""
}
]
}

View File

@ -0,0 +1,27 @@
{
"short_date" : "20190108",
"long_date" : "8 janvier 2019",
"ffmpeg_bin" : "./FFmpeg/ffmpeg",
"chapters" : [
{
"start_timestamp" : "0:03:09",
"end_timestamp" : "0:18:45",
"short_chapter_name" : "chronique-transcriptions"
},
{
"start_timestamp" : "00:18:45",
"end_timestamp" : "01:11:01",
"short_chapter_name" : "dinsic-etalab"
},
{
"start_timestamp" : "01:11:01",
"end_timestamp" : "01:23:38",
"short_chapter_name" : "logiciel-caisse"
},
{
"start_timestamp" : "01:23:38",
"end_timestamp" : "01:29:58",
"short_chapter_name" : "annonces"
}
]
}

View File

@ -0,0 +1,12 @@
{
"short_date" : "20190115",
"long_date" : "15 janvier 2019",
"ffmpeg_bin" : "./FFmpeg/ffmpeg",
"chapters" : [
{
"start_timestamp" : "00:16:27",
"end_timestamp" : "01:29:40",
"short_chapter_name" : "CADA"
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

View File

@ -0,0 +1,148 @@
#!/usr/bin/perl
use strict;
use Getopt::Long;
use JSON;
use Data::Dumper;
my ($help,$config,$verbose,$dryrun);
my $meta_data_script = "lav-outils/podcasts/scripts/make-metadata-image-podcast.sh";
my $verbose;
GetOptions ("help" => \$help,
"config=s" => \$config,
"verbose" => \$verbose,
"dryrun" => \$dryrun);
if($help) {
usage();
} elsif( not $config ) {
print " /!\\ Missing config arg\n\n";
usage();
}
sub usage {
print <<EOS
Exec commands to cut and process LAV! podcast with json file containing the timestamps and sections to be cut.
Needs JSON perl library (apt install libjson-perl)
$0 --config conf_file.json
--config conf_file.json the configuration file containing stuff
--help show this message
--verbose increase verbosity
--dryrun print commands without executing them
EOS
;
}
sub read_config {
my ($filename) = @_;
my $json_text = do { #read all the file in one shot
open(my $json_fh, "<:encoding(UTF-8)", $filename)
or die("Can't open \$filename\": $!\n");
local $/;
<$json_fh>
};
my $json = JSON->new;
my $data = $json->decode($json_text);
return $data;
}
sub process {
my ($config,$verbose,$dryrun)=@_;
my $data = read_config($config);
my $short_date = $data->{short_date};
my $long_date = $data->{long_date};
my $source_name = "libre-a-vous-$short_date";
my $title = "Libre à vous ! du $long_date sur Cause Commune";
my $ffmpeg_bin = $data->{ffmpeg_bin};
for my $chapter (values @{$data->{chapters}}) {
my $start = $chapter->{start_timestamp};
my $end = $chapter->{end_timestamp};
my $short_chapter_name = $chapter->{short_chapter_name};
# cutting chapter
my $command = "$ffmpeg_bin -y -i $source_name.ogg -vn -acodec copy -ss \"$start\" -to \"$end\" $source_name-$short_chapter_name.ogg";
if($dryrun) {
print "$command\n";
} else {
my @ret = `$command`;
if($?) {
print "Error while cutting $short_chapter_name\n";
if($verbose) {
print Dumper @ret;
print Dumper $data;
return 0;
}
}
}
# putting metadata
my $url = "https://media.april.org/audio/radio-cause-commune/libre-a-vous/emissions/$short_date/$source_name-$short_chapter_name.ogg";
my $command = "$meta_data_script -s \"$source_name-$short_chapter_name.ogg\" -d \"output.ogg\" -u \"$url\" -t \"$title\" -p \"$ffmpeg_bin\"";
if($dryrun) {
print "$command\n";
} else {
my @ret = `$command`;
if($?) {
print "Error while setting metadata in $short_chapter_name\n";
if($verbose) {
print Dumper @ret;
print Dumper $data;
return 0;
}
}
}
my $command = "mv output.ogg $source_name-$short_chapter_name.ogg";
if($dryrun) {
print "$command\n";
} else {
my @ret = `$command`;
if($?) {
print "Error while renaming $short_chapter_name\n";
if($verbose) {
print Dumper @ret;
print Dumper $data;
return 0;
}
}
}
}
# putting metadata in main podcast
my $url = "https://media.april.org/audio/radio-cause-commune/libre-a-vous/emissions/$short_date/$source_name.ogg";
my $command = "$meta_data_script -s \"$source_name.ogg\" -d \"output.ogg\" -u \"$url\" -t \"$title\" -p \"$ffmpeg_bin\"";
if($dryrun) {
print "$command\n";
} else {
my @ret = `$command`;
if($?) {
print "Error while setting metadata in $source_name\n";
if($verbose) {
print Dumper @ret;
print Dumper $data;
return 0;
}
}
}
my $command = "mv output.ogg $source_name.ogg";
if($dryrun) {
print "$command\n";
} else {
my @ret = `$command`;
if($?) {
print "Error while renaming $source_name\n";
if($verbose) {
print Dumper @ret;
print Dumper $data;
return 0;
}
}
}
}
process($config,$verbose,$dryrun);

View File

@ -0,0 +1,50 @@
#!/bin/bash
usage() { echo "$0 -s source_file -d destination_file -u http://... -t \"title\" -p path/to/ffmpeg/binary"; exit 0; }
[ $# -eq 0 ] && usage
while getopts "s:d:u:t:p:h" arg; do
case $arg in
s)
source=${OPTARG}
;;
d)
destination=${OPTARG}
;;
u)
url=${OPTARG}
;;
t)
title=${OPTARG}
;;
p)
FFmpegBin=${OPTARG}
;;
h | *) # Display help.
usage
exit 0
;;
esac
done
if [ ! -f $source ]; then
echo "File $source does not exist"
usage
exit 1
fi
if [ ! -f "$FFmpegBin" ]; then
echo "$FFmpegBin is not executable"
usage
exit 1
fi
image="lav-outils/images/image-pour-etiqueter-podcast.jpg"
fichiertemp="$(command mktemp -t "tmp.XXXXXXXXXX.ogg")"
(echo -en ";FFMETADATA1\nMETADATA_BLOCK_PICTURE=";(i=${image};t=3;m="image/jpeg";eval "w=`identify-im6 "$i"|awk '{g=$3;sub("x"," h=",g);print g;d=$5;gsub(/-.*/,"",d);print " d=" d}'`"; echo -en "\x00\x00\x00\x$(printf '%02x' $t)\x00\x00\x00\x$(printf '%02x' `echo -n "$m"|wc -c`)$m\x00\x00\x00\x00$(printf '%08x' $w|sed 's/../\\x&/g')$(printf '%08x' $h|sed 's/../\\x&/g')$(printf '%08x' $d|sed 's/../\\x&/g')\x00\x00\x00\xff$(printf '%08x' `stat -c '%s' "$i"`|sed 's/../\\x&/g')";cat "$i")|base64 --wrap=0) > i.meta
${FFmpegBin} -y -i ${source} -acodec copy -map 0:0 -map_metadata -1 -metadata title="${title}" -metadata copyright="Diffusée selon les termes dau moins une des licences suivantes : licence Art libre version 1.3 ou ultérieure http://artlibre.org/licence/lal/, licence Creative Commons By Sa version 2.0 ou ultérieure http://creativecommons.org/licenses/by-sa/2.0/fr/ et licence GNU FDL version 1.3 ou ultérieure http://www.gnu.org/licenses/fdl-1.3.html" -metadata artist="April - Cause Commune" -metadata contact="${url}" ${fichiertemp}
${FFmpegBin} -y -i ${fichiertemp} -i i.meta -acodec copy -map 0:0 -map_metadata 1 ${destination}
rm ${fichiertemp}
rm i.meta