Lazy Diary @ Hatena Blog

PowerShell / Java / miscellaneous things about software development, Tips & Gochas. CC BY-SA 4.0/Apache License 2.0

How to convert from ADIF AAC to another format (ffmpeg and libav can't handle it)

Context:

You have some AAC ADIF files and you want to convert them into MP3 (and the like) format.

Problem:

ffmpeg and libav don’t (and will never) support ADIF AAC files because it is “bad format”.

Solution:

You can convert an ADIF AAC files into a ordinary (handled with ffmpeg) .m4a file with this adif2mp4.exe on this page: https://rtfreesoft.blogspot.jp/2009_10_01_archive.html

If you use Ubuntu Linux 16.04, you can run adif2.exe from Wine 1.6.2 (installed from Ubuntu 16.04 apt repository). For example, you can convert all *.AAC files in current directory into .m4a format:

$ for i in *.AAC; do wine ../bin/adif2mp4.exe $i `basename $i .AAC`.m4a; done

Once the files are converted to .m4a format, you can handle them with ffmpeg like this:

$ for i in *.m4a; do ffmpeg -i $i `basename $i .m4a`.mp3; done

You should not pass the result of Get-ChildItem into Get-Content (and the like) directly

Context:

You can pass the result of Get-ChildItem into Get-Content directly:

PS /home/satob/tmp> Get-ChildItem | Where-Object { $_.Name -like "*.csv" } | ForEach-Object { Get-Content $_ }          
"a","x"
"b","2"
...

Problem:

You cannot pass the result of Get-ChildItem into Get-Content directly when you Get-ChildItem from other than current directory:

PS /home/satob> Get-ChildItem /tmp | Where-Object { $_.Name -like "*.csv" } | ForEach-Object { Get-Content $_ }         
Get-Content : Cannot find path '/home/satob/foobar.csv' because it does not exist.
At line:1 char:80
+ ... -Object { $_.Name -like "*.csv" } | ForEach-Object { Get-Content $_ }
+                                                          ~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (/home/satob/foobar.csv:String) [Get-Content], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

It is troublesome because the problem will not occur when you test with the files in current directory.

Reason:

The result of Get-ChildItem is handled as relative path when you pass them to Get-Content.

Note: The problem will not occur even without FullName when you use wildcard with Get-ChildItem.

PS /home/satob> Get-ChildItem tmp/*.csv | ForEach-Object { Get-Content $_ }                                             
"a","x"
"b","2"
...

Solution:

You should specify FullName property explicitly:

PS /home/satob> Get-ChildItem tmp/ | Where-Object { $_.Name -like "*.csv" } | ForEach-Object { Get-Content $_.FullName }
"a","x"
"b","2"
...

You can also use FullName property with wildcards:

PS /home/satob> Get-ChildItem tmp/*.csv | ForEach-Object { Get-Content $_.FullName }                                    
"a","x"
"b","2"
...

Note: You should not use Name property with or without wildcards. It contains relative path:

PS /home/satob> Get-ChildItem tmp/ | Where-Object { $_.Name -like "*.csv" } | ForEach-Object { Get-Content $_.Name }    
Get-Content : Cannot find path '/home/satob/a.csv' because it does not exist.
At line:1 char:80
+ ... ct { $_.Name -like "*.csv" } | ForEach-Object { Get-Content $_.Name }
+                                                     ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (/home/satob/a.csv:String) [Get-Content], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand
PS /home/satob> Get-ChildItem tmp/*.csv | ForEach-Object { Get-Content $_.Name }                                        
Get-Content : Cannot find path '/home/satob/a.csv' because it does not exist.
At line:1 char:44
+ Get-ChildItem tmp/*.csv | ForEach-Object { Get-Content $_.Name }
+                                            ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (/home/satob/a.csv:String) [Get-Content], ItemNotFoundException
    + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

You cannot use -Encoding option with Import-Csv in PowerShell 2.0

Context:

Problem:

In PowerShell 2.0, Import-Csv cmdlet doesn’t have -Encoding option.

Solution:

If you want to read a CSV file without CRLF in cells, you can use Get-Content -Encoding and ConvertFrom-Csv like:

PS > Get-Content -Encoding UTF8 ./foobar.csv | ConvertFrom-Csv

If you want to read a CSV file with CRLF in cells, you should convert the CSV file to UTF-16 with BOM, and read the file with Import-Csv (Import-Csv can recognize UTF-16 encoding automatically even in PowerShell 2.0):

PS > Get-Content -Encoding UTF8 ./foobar.csv | Out-File -Encoding Unicode -Path "./foobar-utf16.csv"
PS > Import-Csv ./foobar-utf16.csv

Difference of acceptable parameters for -Encoding option

Acceptable parameters for -Encoding option are different for Get-Content, Set-Content, Export-Csv, Import-Csv, and Out-File.

# cmdlet Default ASCII UTF-7 UTF-8 UTF-16LE UTF-16BE UTF-32LE UTF-32BE Byte Default OEM String Unknown
1 Get-Content Ascii Ascii UTF7 UTF8 Unicode BigEndianUnicode UTF32 BigEndianUTF32 Byte Default Oem String Unknown
2 Set-Content Ascii Ascii UTF7 UTF8 Unicode BigEndianUnicode UTF32 BigEndianUTF32 Byte Default Oem String Unknown
3 Export-Csv ASCII ASCII UTF7 UTF8 Unicode BigEndianUnicode UTF32 - - Default OEM - -
4 Import-Csv ASCII ASCII UTF7 UTF8 Unicode BigEndianUnicode UTF32 - - Default OEM - -
5 Out-File default ascii utf7 utf8 unicode bigendianunicode utf32 - - default oem string unknown
PS > Get-Content -Encoding
Ascii             BigEndianUTF32    Default           String            Unknown           UTF7
BigEndianUnicode  Byte              Oem               Unicode           UTF32             UTF8
PS > Set-Content -Encoding
Ascii             BigEndianUTF32    Default           String            Unknown           UTF7
BigEndianUnicode  Byte              Oem               Unicode           UTF32             UTF8
PS > Import-Csv -Encoding
ASCII             Default           Unicode           UTF7
BigEndianUnicode  OEM               UTF32             UTF8
PS > Export-Csv -Encoding
ASCII             Default           Unicode           UTF7
BigEndianUnicode  OEM               UTF32             UTF8
PS > Out-File -Encoding
ascii             default           string            unknown           utf7
bigendianunicode  oem               unicode           utf32             utf8

Functional limitation of The Nu Html Checker (v.Nu)

Problem:

The Nu Html Checker (v.Nu) is useful HTML validator. It can be used not only from a web browser, but also from command line. But, this validator has some functional limitations (for both web interface and CLI version).

  • v.Nu cannot handle non-Unicode files. For example, you will get errors like below for Shift_JIS files:
~/download/dist$ java -jar vnu.jar sjis.html 
"file:/home/satob/download/dist/sjis.html":11.40-11.40: error: Malformed byte sequence: “83”.
"file:/home/satob/download/dist/sjis.html":11.42-11.42: error: Malformed byte sequence: “81”.
"file:/home/satob/download/dist/sjis.html":11.44-11.44: error: Malformed byte sequence: “83”.
  • v.Nu treats an HTML 4.01 doctype as obsolete doctype and shows an error:
~/download/dist$ java -jar vnu.jar html4.html
"file:/home/satob/download/dist/index.html":1.1-3.44: info warning: Obsolete doctype. Expected “<!DOCTYPE html>”.
  • Partial HTML (often used for Single Page Applications) gets error:
~/download/dist$ java -jar vnu.jar partial.html 
"file:/home/satob/download/dist/partial.html":1.1-1.19: error: Start tag seen without seeing a doctype first. Expected “<!DOCTYPE html>”.
  • Custom attributes (and tags) for JavaScript frameworks are treated as invalidate attribute:
~/download/dist$ java -jar vnu.jar angular.html 
"file:/home/satob/download/dist/angular.html":9.1-9.15: error: Attribute “ng-app” not allowed on element “div” at this point.
"file:/home/satob/download/dist/angular.html":12.10-12.44: error: Attribute “ng-model” not allowed on element “input” at this point.
"file:/home/satob/download/dist/angular.html":13.1-13.18: error: Attribute “ng-bind” not allowed on element “p” at this point.

In other words, v.Nu can handle only UTF-8 encoded, HTML5, full-length, and plain HTML.

Reason:

It seems by design.

Solution:

v.Nu doesn’t have options for these valid-depending-on-context HTML. There is no workaround for this problem, so use another HTML validator.

For example, The Eclipse built-in HTML validator can handle non-Unicode files, HTML 4.01, partial HTML, and has option for non-standard tags and attributes.