sandreas / m4b-tool

m4b-tool is a command line utility to merge, split and chapterize audiobook files such as mp3, ogg, flac, m4a or m4b
MIT License
1.16k stars 75 forks source link

Get error "Input is not a file" using docker image #56

Closed Borewit closed 4 years ago

Borewit commented 4 years ago

What an amazing project you have put together.

Issue

After building the docker image without any issue, I am not able to split an m4b file

Following error is thrown:

[maarten@zbook m4b-tool]$ m4b-tool split --audio-format aac data/issue-120.m4b 

In AbstractCommand.php line 525:

  Input is not a file

Issue

Background, I am adding MP4 chapter support in music-metadata. Which I believe is working. Problem is, it makes most of my MP4 sample useless. I stripped of the MDAT payload of most of the files, and maybe some more, to get to workable size. I was hoping my splitting, trimming and joining, I could shrink the originals, in such a way there are chapters, but the audio content is limited to something like a a second.

sandreas commented 4 years ago

Thanks :-)

I confirm that there is something wrong with the split command in general - I'll take a look in the next days and publish a nightly as soon as it is all fixed.

Borewit commented 4 years ago

That would be great @sandreas. If you have some advice how to shrink audio books more effective I would love to hear that. If you came across some useful test files as well.

sandreas commented 4 years ago

Should be fixed in latest pre-release - don't forget to read the notes. https://github.com/sandreas/m4b-tool/releases/tag/latest

Borewit commented 4 years ago

After rebuilding the docker image, I still have the same issue. Should I clean something before rebuilding with docker build . -t m4b-tool?

sandreas commented 4 years ago

You have to change the download link in the dockerfile or provide a build argument... see https://github.com/sandreas/m4b-tool#installation:

It is also possible to switch version of m4b-tool used in the docker image by providing a custom link as build-arg parameter (even experimental builds linked in issues should work):

docker build . --build-arg M4B_TOOL_DOWNLOAD_LINK=https://github.com/sandreas/m4b-tool/files/3851425/m4b-tool.tar.gz -t m4b-tool
Borewit commented 4 years ago

I have done the following, on Fedora:

# Prepare OS requirements:
dnf install php
dnf install composer

# Build phar
cd m4b-tool
git checkout master
git pull
composer update
./build

# Build docker using the latest phar just build
docker build . -t m4b-tool
alias m4b-tool='docker run -it --rm -u $(id -u):$(id -g) -v "$(pwd)":/mnt m4b-tool'

# Split audio book
m4b-tool split data/WEB01-06_librivox.m4b

Same error, that should use the latest branch version right?

sandreas commented 4 years ago

Same error, that should use the latest branch version right?

Hehe, unfortunately no, this does not use the latest branch version.

Since docker is something i dirty hacked because i did not start with a Dockerfile... So Docker is not used to build m4b-tool but just to run it. To run it, the docker image downloads the latest release m4b-tool version during the build phase of the image.

So the documentation is accurate (is your pull request correct then? i think you misunderstood the docker usage, because it behaves different than in most other projects). You won't need to install php or composer on your host. Just docker is needed:

# clone m4b-tool repository
git clone https://github.com/sandreas/m4b-tool.git

# change directory
cd m4b-tool

# THIS IS NOT WHAT YOU NEED - because it is for stable
# build docker image - this will take a while
# docker build . -t m4b-tool => this is for latest stable

# THIS IS WHAT YOU NEED - you want the latest pre-release, so you have to add one option:
docker build . --build-arg M4B_TOOL_DOWNLOAD_LINK=https://github.com/sandreas/m4b-tool/files/3851425/m4b-tool.tar.gz -t m4b-tool

# create an alias for m4b-tool running docker
alias m4b-tool='docker run -it --rm -u $(id -u):$(id -g) -v "$(pwd)":/mnt m4b-tool'

# testing the command
m4b-tool --version
Borewit commented 4 years ago

Yeah I first thought it was downloading the distribution, which is indeed confusing that the docker is deviation from repository version checked out.

This gave me the impression would be able to use a local build:

https://github.com/sandreas/m4b-tool/blob/03a08496a364f86ca513b097247fee12d5a33f15/Dockerfile#L110-L112

Anyway I tried your suggested path, with the

$ m4b-tool -- version

m4b-tool latest-20-g03a0849

Still the Input is not a file error 🤷

sandreas commented 4 years ago

Mmh.. this is indeed confusing. Well, perhaps it has to do something with my latest experiments with branches and m4b-tool plugins (which was not very effective).

I did a new build (removed the old one). This one definetely works for me (tested on my system exactly like i described):

docker build . --build-arg M4B_TOOL_DOWNLOAD_LINK=https://github.com/sandreas/m4b-tool/files/3854214/m4b-tool.tar.gz -t m4b-tool

m4b-tool --version
# m4b-tool latest-1-g954ca64

m4b-tool -v split --audio-format aac "an-m4b-file.m4b"

cd *splitted
ls
# 001-1.1.1.aac 
# 002-1.1.2.aac 
# 003-1.1.3.aac 
# cover.jpg
# description.txt
Borewit commented 4 years ago

If I repeat your steps I get: m4b-tool --version

# m4b-tool latest-22-g7ba772e

Different version, should be latest-1-g954ca64 right?

moving on...

[borewit@zbook m4b-tool]$ m4b-tool -v split data/WEB01-06_librivox.m4b

In AbstractCommand.php line 340:

  [Exception]          
  Input is not a file  

Exception trace:
  at phar:///usr/local/bin/m4b-tool/src/library/M4bTool/Command/AbstractCommand.php:340
 M4bTool\Command\AbstractCommand->ensureInputFileIsFile() at phar:///usr/local/bin/m4b-tool/src/library/M4bTool/Command/SplitCommand.php:91
 M4bTool\Command\SplitCommand->execute() at phar:///usr/local/bin/m4b-tool/vendor/symfony/console/Command/Command.php:255
 Symfony\Component\Console\Command\Command->run() at phar:///usr/local/bin/m4b-tool/vendor/symfony/console/Application.php:934
 Symfony\Component\Console\Application->doRunCommand() at phar:///usr/local/bin/m4b-tool/vendor/symfony/console/Application.php:273
 Symfony\Component\Console\Application->doRun() at phar:///usr/local/bin/m4b-tool/vendor/symfony/console/Application.php:149
 Symfony\Component\Console\Application->run() at phar:///usr/local/bin/m4b-tool/bin/m4b-tool.php:44
 require() at /usr/local/bin/m4b-tool:10
sandreas commented 4 years ago

Did you SURELY remove the existing dist/m4b-tool.tar.gz before?

Well, here is the last thing you could try:

# ensure, that no old repo is existing
rm -rf /tmp/m4b-tool
cd /tmp
git clone https://github.com/sandreas/m4b-tool.git
cd m4b-tool
docker build . --build-arg M4B_TOOL_DOWNLOAD_LINK=https://github.com/sandreas/m4b-tool/files/3854214/m4b-tool.tar.gz -t m4b-tool
alias m4b-tool='docker run -it --rm -u $(id -u):$(id -g) -v "$(pwd)":/mnt m4b-tool'
m4b-tool --version

if this does not work

cd /tmp/m4b-tool
mkdir dist
cd dist
wget https://github.com/sandreas/m4b-tool/files/3854214/m4b-tool.tar.gz
cd ..
docker build . -t m4b-tool
alias m4b-tool='docker run -it --rm -u $(id -u):$(id -g) -v "$(pwd)":/mnt m4b-tool'
m4b-tool --version

and if this does not work, open the Dockerfile and change manually

M4B_TOOL_DOWNLOAD_LINK=https://github.com/sandreas/m4b-tool/files/3854214/m4b-tool.tar.gz 

If this does not help and you are still on the old version, i have no idea what is wrong...

Borewit commented 4 years ago

I did not delete dist/m4b-tool.tar.gz before, now I did, and the version seems correct now: m4b-tool latest-1-g954ca64

So the version is in sync now.

So sorry, same error though.

Thank you so much for all your effort.

If have 3 m4b files, which I want to use for unit testing. I would like to strip of most of the audio content, keep the metadata, and keep a chapter list (offset can be adjusted ofcourse). Can you please help me with that?

sandreas commented 4 years ago

Well... i try to. But since there is no hint, what could be wrong with your docker image, it is a bit difficult to find out, what your problem might be. It works for me.

You could try to add the --debug flag (m4b-tool split --debug ...) to find out, whats happening. It will give you more output and should create a m4b-tool.log file, where all of the executed commands are logged. In general it will put out something similar to this (at least on my system):

# extract 6 minutes 44 seconds from testing.m4b to part1-tmp.m4b (extracting only works good using the same codec)
'ffmpeg' '-hide_banner' '-i' 'testing.m4b' '-vn' '-ss' '00:00:00.000' '-t' '00:06:44.342' '-map_metadata' 'a' '-map' 'a' '-acodec' 'copy' '-f' 'mp4' 'part1-tmp.m4b'

# convert part1-tmp.m4b to part1.aac
'ffmpeg' '-hide_banner' '-i' 'part1-tmp.m4b'  '-map_metadata' '-c' 'copy' '-id3v2_version' '3' '-max_muxing_queue_size' '9999' '-movflags' '+faststart' '-vn' '-ab' '64k' '-ar' '22050' '-ac' '0' '-f' 'adts' 'part1.aac'

Perhaps this does help you to skip m4b-tool in favor of ffmpeg

Borewit commented 4 years ago

I am sorry, with help I meant, maybe you can do the conversion for me on your end. I appreciate all the effort you put into the project and trying to get these issues fixed.

[borewit@zbook m4b-tool]$ m4b-tool --debug split data/WEB01-06_librivox.m4b 
'ffmpeg' '-hide_banner' '-codecs'
PHP Warning:  touch(): Unable to create file m4b-tool.log because Permission denied in phar:///usr/local/bin/m4b-tool/src/library/M4bTool/Command/AbstractCommand.php on line 240
Debug file m4b-tool.log is not writable
PHP Warning:  file_put_contents(): Filename cannot be empty in phar:///usr/local/bin/m4b-tool/src/library/M4bTool/Command/AbstractCommand.php on line 247

In AbstractCommand.php line 340:

  [Exception]          
  Input is not a file  

Exception trace:
  at phar:///usr/local/bin/m4b-tool/src/library/M4bTool/Command/AbstractCommand.php:340
 M4bTool\Command\AbstractCommand->ensureInputFileIsFile() at phar:///usr/local/bin/m4b-tool/src/library/M4bTool/Command/SplitCommand.php:91
 M4bTool\Command\SplitCommand->execute() at phar:///usr/local/bin/m4b-tool/vendor/symfony/console/Command/Command.php:255
 Symfony\Component\Console\Command\Command->run() at phar:///usr/local/bin/m4b-tool/vendor/symfony/console/Application.php:934
 Symfony\Component\Console\Application->doRunCommand() at phar:///usr/local/bin/m4b-tool/vendor/symfony/console/Application.php:273
 Symfony\Component\Console\Application->doRun() at phar:///usr/local/bin/m4b-tool/vendor/symfony/console/Application.php:149
 Symfony\Component\Console\Application->run() at phar:///usr/local/bin/m4b-tool/bin/m4b-tool.php:44
 require() at /usr/local/bin/m4b-tool:10

split [--logfile [LOGFILE]] [--debug] [-f|--force] [--no-cleanup] [--no-cache] [--ffmpeg-threads [FFMPEG-THREADS]] [--platform-charset [PLATFORM-CHARSET]] [--ffmpeg-param [FFMPEG-PARAM]] [-a|--silence-min-length [SILENCE-MIN-LENGTH]] [-b|--silence-max-length [SILENCE-MAX-LENGTH]] [--max-chapter-length [MAX-CHAPTER-LENGTH]] [--name [NAME]] [--sortname [SORTNAME]] [--album [ALBUM]] [--sortalbum [SORTALBUM]] [--artist [ARTIST]] [--sortartist [SORTARTIST]] [--genre [GENRE]] [--writer [WRITER]] [--albumartist [ALBUMARTIST]] [--year [YEAR]] [--description [DESCRIPTION]] [--longdesc [LONGDESC]] [--comment [COMMENT]] [--copyright [COPYRIGHT]] [--encoded-by [ENCODED-BY]] [--encoder [ENCODER]] [--cover [COVER]] [--skip-cover] [--series [SERIES]] [--series-part [SERIES-PART]] [--remove [REMOVE]] [--ignore-source-tags] [--audio-format [AUDIO-FORMAT]] [--audio-channels [AUDIO-CHANNELS]] [--audio-bitrate [AUDIO-BITRATE]] [--audio-samplerate [AUDIO-SAMPLERATE]] [--audio-codec [AUDIO-CODEC]] [--audio-quality [AUDIO-QUALITY]] [--audio-profile [AUDIO-PROFILE]] [--adjust-for-ipod] [--fix-mime-type] [--trim-silence] [--add-silence [ADD-SILENCE]] [-o|--output-dir [OUTPUT-DIR]] [-p|--filename-template [FILENAME-TEMPLATE]] [--use-existing-chapters-file] [--reindex-chapters] [--fixed-length [FIXED-LENGTH]] [--chapters-filename [CHAPTERS-FILENAME]] [--] <input>

an error occured, that has not been caught:
Array
(
    [type] => 2
    [message] => file_put_contents(): Filename cannot be empty
    [file] => phar:///usr/local/bin/m4b-tool/src/library/M4bTool/Command/AbstractCommand.php
    [line] => 247
)

Files I am trying to "shrink": https://we.tl/t-AnrNnnFf2W

sandreas commented 4 years ago

Ok, unless this has nothing to do with your error description, at least i found a bug when using your files.

One of your files is using a timebase of 1/44100 (I've never seen this before), which led to wrong time values when parsing chapters - and so splitting the file by chapters failed due to too long time values.

I'm on it.

Borewit commented 4 years ago

One of your files is using a timebase of 1/44100 (I've never seen this before), which led to wrong time

Can you give me more details, which file is that? Where is the 1 defined? Which atom (box)?

I just released music-metadata@5.0.0 with m4b chapter support. I found a 7 MB audio book, at least I was able put in a unit tests to proof at least it doing something.

sandreas commented 4 years ago

Can you give me more details, which file is that?

issue-127.m4b

Where is the 1 defined?

ffmpeg shows up a TIMEBASE=1/44100 in its metadata - where mp4chaps works as expected, but since i use the more flexible ffmpeg for detecting meta

ffmpeg -i issue-127.m4b -f ffmetadata issue-127-meta.txt

results in

;FFMETADATA1
major_brand=M4A
minor_version=0
compatible_brands=3gp5isom
Encoding Params=vers
genre=Audiobook
media_type=2
track=1
title=GloriesIreland00-12_librivox
artist=Joseph Dunn
album=The Glories of Ireland
comment=https://archive.org/details/glories_of_ireland_1801_librivox
encoder=Lavf58.20.100
[CHAPTER]
TIMEBASE=1/44100
START=0
END=12789133
title=00 - Preface
[CHAPTER]
TIMEBASE=1/44100
START=12789133
END=78233962
title=01 - The Romance of Irish History
Borewit commented 4 years ago

The first chapter is indeed not starting at 0.

This is what I get out of it:

        {
          sampleOffset: 45056,
          title: '00 - Preface'
        },
        {
          sampleOffset: 12794880,
          title: '01 - The Romance of Irish History'
        },
        {
          sampleOffset: 78258176,
          title: '02 - The Islands of Saints and Scholars'
        },
        {
          sampleOffset: 143667200,
          title: '03 - Irish Monks in Europe'
        },
        {
          sampleOffset: 236867584,
          title: '04 - The Irish and the Sea'
        },
        {
          sampleOffset: 276781056,
          title: '05 - Irish Love of Learning'
        },
        {
          sampleOffset: 322828288,
          title: '06 - Irish Men of Science'
        },
        {
          sampleOffset: 413027328,
          title: '07 - Law in Ireland'
        },
        {
          sampleOffset: 519372800,
          title: '08 - Irish Music'
        },
        {
          sampleOffset: 576909312,
          title: '09 - Irish Metal Work'
        },
        {
          sampleOffset: 612588544,
          title: '10 - Irish Manuscripts'
        },
        {
          sampleOffset: 647822336,
          title: '11 - The Ruins of Ireland'
        }

which I have never compared to a reliable reference, so the offsets may off. But the first chapter does not start at 0, that is correct.

sandreas commented 4 years ago

Ok, the timebase problem should now be fixed with the latest pre-release.