diff --git a/README.md b/README.md index a90c63a..7f36844 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Программа для преобразования электронных книг в видео - + Для помощи используйте ключ '-h' \ No newline at end of file diff --git a/Logo.png b/img/Logo.png similarity index 100% rename from Logo.png rename to img/Logo.png diff --git a/Logo.svg b/img/Logo.svg similarity index 100% rename from Logo.svg rename to img/Logo.svg diff --git a/img/Logo_White.png b/img/Logo_White.png new file mode 100644 index 0000000..40a5862 Binary files /dev/null and b/img/Logo_White.png differ diff --git a/pdf2video b/pdf2video index eed54ea..591bad9 100755 --- a/pdf2video +++ b/pdf2video @@ -13,7 +13,7 @@ common_params=( "h|help|Посмотреть помощь.|||ShowHelp; exit;" "v|version|Посмотреть версию программы.|||echo \$version; exit;" "V|verbose|Подробный вывод.|||verbose=true" -# "|||||" + "k|keep_files|Не удалять временные файлы. Может принимать значения 'yes', 'no'. По умолчанию '!DEFAULT!'.|:|'no'|" ) sound_params=( @@ -30,13 +30,15 @@ sound_params=( video_params=( "o|output|Выходной видео файл.|:|''|" - "k|split|Деление страницы пополам. Может быть либо 'yes', либо 'no'. По умолчанию '!DEFAULT!'.|:|'yes'|" + #"t|split|Деление страницы. Может быть либо 'half' (деление пополам), либо 'time' (плавное перемещение), либо 'no' (целиком). По умолчанию '!DEFAULT!'.|:|'half'|" + "t|split|Деление страницы. Может быть либо 'half' (деление пополам), либо 'no' (целиком). По умолчанию '!DEFAULT!'.|:|'half'|" "W|video_width|Размер видео в пикселях по ширине. По умолчанию '!DEFAULT!'.|:|1920|" "H|video_height|Размер видео в пикселях по высоте. По умолчанию '!DEFAULT!'.|:|1080|" "p|ffmpeg_pre_options|Опции ffmpeg в самом начале. По умолчанию '!DEFAULT!'.|:|'-loop 1 -r 2'|" "P|ffmpeg_options|Опции ffmpeg. По умолчанию '!DEFAULT!'.|:|'-c:v libx264 -tune stillimage -preset ultrafast -crf 20 -shortest -pix_fmt yuv420p'|" "r|page_range|Указывает страницы из выходного файла для обработки. Пример '{1..32}', '{2..10..2}', '\$(seq 5 3 30)'|:|''|" "m|minimum_text_on_page|Минимальное количество символов на странице при котором происходит разделение страницы на две. По умолчанию '!DEFAULT!'.|:|1000|" + "M|minimum_time_on_page|Минимальное количество секунд на страницу. По умолчанию '!DEFAULT!'.|:|5|" # "|||:||" ) @@ -103,30 +105,36 @@ function Text2mp3 { local text_file=$1 local mp3_file=$2 verb="" - [ $verbose ] && verb="-V" + [ $verbose ] && verb="-V " - [ $verbose ] && echo "Найден исполняемый файл для преобразования в звук текста $(GetExec txt2mp3)" - eval "$(GetExec "txt2mp3") -i '${text_file}' -o '${mp3_file}' -e '${emotion}' -s '${speaker}' -S '${speed}' -f '${format}' -q '${quality}' -l '${lang}' '${verb}'" + cmd="$(GetExec "txt2mp3") -i '${text_file}' -o '${mp3_file}' -e '${emotion}' -s '${speaker}' -S '${speed}' -f '${format}' -q '${quality}' -l '${lang}' ${verb}" + [ $verbose ] && echo "Команда для преобразования в звук текста '$cmd'" + eval "$cmd" } function MakeVideo { local page_image_file=$1 local page_mp3_file=$2 local page_mp4_file=$3 + local split=$4 - local resized_page_image_file="${page_image_file}_resized.png" + local resized_page_image_file=$(mktemp -t "MakeVideo_resized_page_image_XXXXXXXXXXX.png" +) ffmpeg -y -i "${page_image_file}" -vf "scale=${video_width}:${video_height}:force_original_aspect_ratio=decrease,pad=${video_width}:${video_height}:(ow-iw)/2:(oh-ih)/2" "${resized_page_image_file}" + video_filter="" + [ $verbose ] && echo "ffmpeg $?" local time_play=$(mp3info -p "%S\n" "${page_mp3_file}") local time_opt="-c:a copy" - if [ ${minimum_time_on_page} -ge ${time_play} ]; then - local add_time=5 # $(( 5 - ${time_play} )) + if [ ${minimum_time_on_page} -ge $(( ${time_play} )) ]; then + local add_time="$minimum_time_on_page" # $(( 5 - ${time_play} )) time_opt="-c:a mp3 -af adelay=${add_time}s:all=true" # [ $verbose ] && echo "time_opt ${time_opt}" fi - ffmpeg ${ffmpeg_pre_options} -i "${resized_page_image_file}" -i "${page_mp3_file}" ${ffmpeg_options} ${time_opt} "${page_mp4_file}" + ffmpeg -y ${ffmpeg_pre_options} -i "${resized_page_image_file}" -i "${page_mp3_file}" ${ffmpeg_options} ${time_opt} ${video_filter} "${page_mp4_file}" + [ $verbose ] && echo "ffmpeg $?" SAVE_IFS=$IFS IFS="" @@ -136,6 +144,28 @@ function MakeVideo { rm "${resized_page_image_file}" } +function SplitText { + local out_array_name=$1[@] + local source_text=$2 + local split_size=$3 + out_array=("${!out_array_name}") + + local space_char=" " + local cur_text="" + for ((i=1;i<=${#source_text};i++)); do + local cur_char=${source_text:$i-1:1} + cur_text="${cur_text}${cur_char}" + if [ "$cur_char" = "$space_char" ] && [ ${#cur_text} -ge $split_size ] || [ $i = ${#source_text} ]; then + SAVE_IFS=$IFS + IFS="" + split_source_text_array+=(${cur_text}) + IFS=$SAVE_IFS + + cur_text="" + fi + done +} + [ $verbose ] && echo "Всего страниц $page_count" for ((page=1;page<=${page_count};page++)); do @@ -159,76 +189,65 @@ for ((page=1;page<=${page_count};page++)); do [ $verbose ] && echo "------------------------------------------------" [ $verbose ] && echo "Обрабатываем страницу №$page" - page_text_file="${input_file}_${page}.txt" - page_image_file="${input_file}_${page}" + page_text_file=$(mktemp -t "pdf2video_page_text_file_${page}_XXXXXXXXXXX.mp3" +) + page_image_file=$(mktemp -t "pdf2video_page_image_file_${page}_XXXXXXXXXXX.png" +) pdftotext -f $page -l $page "${input_file}" "$page_text_file" - pdftoppm -r 300 -f $page -l $page -png -singlefile "${input_file}" "$page_image_file" - - page_image_file="${page_image_file}.png" + convert -density 300 "${input_file}[$(( $page - 1))]" -quality 90 "$page_image_file" source_text="$(cat "${page_text_file}")" - if [ "$split" = "yes" ] && [ ${#source_text} -ge $minimum_text_on_page ]; then + if [ "$split" = "half" ] && [ ${#source_text} -ge $minimum_text_on_page ]; then - space_char=" " split_size=$(( ${#source_text} / 2 + 2)) # Половина с небольшим запасом - file_index=0 - for ((i=1;i<=${#source_text};i++)); do - cur_char=${source_text:$i-1:1} - cur_text="${cur_text}${cur_char}" - if [ "$cur_char" = "$space_char" ] && [ ${#cur_text} -ge $split_size ] || [ $i = ${#source_text} ]; then - let file_index+=1 + split_source_text_array=() - echo "$cur_text" > "${page_text_file}_half${file_index}" - - cur_text="" - fi - done + SplitText split_source_text_array "$source_text" $split_size - file_txt_half1="${page_text_file}_half1" - file_txt_half2="${page_text_file}_half2" - - page_mp3_file_half1="${file_txt_half1}.mp3" - page_mp3_file_half2="${file_txt_half2}.mp3" + page_mp3_file_half1=$(mktemp -t "pdf2video_page_mp3_file_half1_XXXXXXXXXXX.mp3" +) + page_mp3_file_half2=$(mktemp -t "pdf2video_page_mp3_file_half2_XXXXXXXXXXX.mp3" +) - Text2mp3 "$file_txt_half1" "$page_mp3_file_half1" - Text2mp3 "$file_txt_half2" "$page_mp3_file_half2" + Text2mp3 <( echo "${split_source_text_array[0]}" ) "$page_mp3_file_half1" + Text2mp3 <( echo "${split_source_text_array[1]}" ) "$page_mp3_file_half2" width=$(identify -format "%w" "$page_image_file")> /dev/null height=$(identify -format "%h" "$page_image_file")> /dev/null height_half=$(( $height / 2 + $height / 20 )) - page_image_file_half1="${page_image_file}_half1.png" - page_image_file_half2="${page_image_file}_half2.png" + page_image_file_half1=$(mktemp -t "pdf2video_page_image_file_half1_XXXXXXXXXXX.png" +) + page_image_file_half2=$(mktemp -t "pdf2video_page_image_file_half2_XXXXXXXXXXX.png" +) - # format (widthxheight+left+top / wxh+l+t) - convert "$page_image_file" -crop ${width}x${height_half}+0+0 "$page_image_file_half1" - convert "$page_image_file" -crop ${width}x${height_half}+0+$(( $height - $height_half )) "$page_image_file_half2" + # convert format (widthxheight+left+top / wxh+l+t) + convert "$page_image_file" -crop ${width}x${height_half}+0+0 "${page_image_file_half1}" + convert "$page_image_file" -crop "${width}x${height_half}+0+$(( $height - $height_half ))" "${page_image_file_half2}" page_mp4_file_half1="${input_file}_${page}_half1.mp4" page_mp4_file_half2="${input_file}_${page}_half2.mp4" - MakeVideo "$page_image_file_half1" "$page_mp3_file_half1" "$page_mp4_file_half1" + MakeVideo "${page_image_file_half1}" "$page_mp3_file_half1" "$page_mp4_file_half1" "$split" - MakeVideo "$page_image_file_half2" "$page_mp3_file_half2" "$page_mp4_file_half2" + MakeVideo "${page_image_file_half2}" "$page_mp3_file_half2" "$page_mp4_file_half2" "$split" rm "$page_image_file_half1" rm "$page_image_file_half2" - rm "$file_txt_half1" - rm "$file_txt_half2" rm "$page_mp3_file_half1" rm "$page_mp3_file_half2" else - page_mp3_file="${page_text_file}.mp3" + page_mp3_file=$(mktemp -t "pdf2video_page_mp3_file_XXXXXXXXXXX.mp3") Text2mp3 "$page_text_file" "$page_mp3_file" page_mp4_file="${input_file}_${page}.mp4" - MakeVideo "$page_image_file" "$page_mp3_file" "$page_mp4_file" + MakeVideo "$page_image_file" "$page_mp3_file" "$page_mp4_file" "$split" rm "$page_mp3_file" @@ -242,12 +261,15 @@ done SAVE_IFS=$IFS IFS="" [ $verbose ] && echo "Объединяем файлы ${video_file_names_array[*]} в $out_file" -ffmpeg -f concat -safe 0 -i <(for ((i = 0; i < ${#video_file_names_array[@]}; i++)) do echo "file '$PWD/${video_file_names_array[$i]}'"; done) -acodec copy -vcodec copy "$out_file" +ffmpeg -y -f concat -safe 0 -i <(for ((i = 0; i < ${#video_file_names_array[@]}; i++)) do echo "file '$PWD/${video_file_names_array[$i]}'"; done) -acodec copy -vcodec copy "$out_file" +[ $verbose ] && echo "ffmpeg $?" for ((i = 0; i < ${#video_file_names_array[@]}; i++)) do f="${video_file_names_array[$i]}" - [ $verbose ] && echo "Удаляем файл '$f'" - rm "$f" + [ "$keep_files" = "no" ] && { + rm "$f" + [ $verbose ] && echo "Удаляем файл '$f'" + } done IFS=$SAVE_IFS diff --git a/txt2mp3 b/txt2mp3 index 3ec6ef9..3c07249 100755 --- a/txt2mp3 +++ b/txt2mp3 @@ -132,7 +132,8 @@ for ((i = 0; i < ${#txt_array[@]}; i++)) do #[ $verbose ] && echo $cur_text >> "out.txt" - audio_file_name="${input_file}_${file_index}.mp3" + audio_file_name=$(mktemp -t "txt2mp3_audio_file_name_${file_index}_XXXXXXXXXXX.mp3" +) [ $verbose ] && echo -en "\nЗагрузка аудио в файл '$audio_file_name'...\n" @@ -149,7 +150,8 @@ done [ $verbose ] && echo "Объединяем файлы ${audio_file_names_array[*]} в $out_file" -ffmpeg -f concat -safe 0 -i <(for ((i = 0; i < ${#audio_file_names_array[@]}; i++)) do echo "file '$PWD/${audio_file_names_array[$i]}'"; done) -acodec copy -vcodec copy ${ffmpeg_opt} "$out_file" +ffmpeg -y -f concat -safe 0 -i <(for ((i = 0; i < ${#audio_file_names_array[@]}; i++)) do echo "file '${audio_file_names_array[$i]}'"; done) -acodec copy -vcodec copy ${ffmpeg_opt} "$out_file" +[ $verbose ] && echo "ffmpeg $?" for ((i = 0; i < ${#audio_file_names_array[@]}; i++)) do f="${audio_file_names_array[$i]}"