Bất kỳ phần mềm phát hiện nhịp cho Linux? [đóng cửa]


29

Amarok 2 có thể tìm kiếm thông qua bộ sưu tập nhạc bằng cách sử dụng trường 'bpm' của thẻ ID3v2. Điều đó sẽ rất hay khi thử lại toàn bộ bộ sưu tập nhạc để tôi có thể tìm thấy "tâm trạng" của bản nhạc tôi thích.

Tuy nhiên tôi đã không tìm thấy bất kỳ phần mềm phát hiện nhịp nào có thể giúp tôi. Bạn đã bao giờ sử dụng một? CLI, tốt nhất là. Ngoài ra, tôi quan tâm nếu có bất cứ điều gì giống nhau để gắn thẻ FLAC với cùng trường 'bpm'.

Cảm ơn! :)

PS Tôi biết có một tính năng tâm trạng tốt, tuy nhiên nó vô dụng để tìm kiếm.


3
bạn đã thấy trang này chưa? mmartins.com/mmartins/bpmdetection/bpmdetection.asp Có vẻ chính xác những gì bạn đang tìm kiếm.
DaveParillo

@DaveParillo rằng liên kết "tâm trạng của một bản nhạc" là một liên kết đến đĩa cứng của bạn và vô dụng với bất kỳ ai trừ bạn
Justin Smith

@Justin Smith, ý anh là một tập tin trong tài liệu BpmDj :) Đây là phiên bản trực tuyến: bpmdj.yellowcouch.org/clustering.html
kolypto

@Justin - xin lỗi - ngón tay kích hoạt co giật, tôi đoán vậy.
DaveParillo

Câu trả lời:


17

Tại trang DaveParillo đề nghị tôi đã tìm thấy dự án BpmDj . Nó có một bpmcounttệp thực thi tính toán bpm rất hay: nó xử lý mp3 cũng như flac:

161.135 Metallica/2008 - Death Magnetic/01-That Was Just Your Life.flac
63.5645 Doom3.mp3

Điều duy nhất còn lại là thử lại bộ sưu tập. Tôi sẽ cập nhật câu trả lời này bất cứ khi nào tôi thành công. Cảm ơn! :)


Bước 1

Chạy bpmcountngược lại toàn bộ bộ sưu tập và lưu trữ kết quả vào tệp văn bản. Vấn đề là bpmcountthỉnh thoảng gặp sự cố và cố gắng ăn tối đa 2GB bộ nhớ khi nó xử lý một số tệp vì vậy chúng ta nên cung cấp nó với tên tệp từng cái một. Như thế này:

musicdir='/home/ootync/music'
find "$musicdir" -iregex ".*\.\(mp3\|ogg\|flac\|ape\)" -exec bpmcount {} \; \
    | fgrep "$musicdir" > "$musicdir/BPMs.txt"

Bước 2

Chúng tôi sẽ cần một số gói bổ sung : apt-get install vorbis-tools flac python-mutagen. Bây giờ hãy xem làm thế nào thẻ 'bpm' có thể được thêm vào:

mid3v2 --TBPM 100 doom3.mp3
vorbiscomment -a -t "BPM=100" mother.ogg
metaflac --set-tag="BPM=100" metallica.flac

Than ôi, tôi không có * .ape track

Bây giờ chúng tôi có các BPM và toàn bộ bộ sưu tập nên được thử lại. Đây là kịch bản:

cat "$musicdir/BPMs.txt" | while read bpm file ; do
    bpm=`printf "%.0f" "$bpm"` ;
    case "$file" in 
        *.mp3) mid3v2 --TBPM "$bpm" "$file" > /dev/null ;; 
        *.ogg) vorbiscomment -a -t "BPM=$bpm" "$file" ;; 
        *.flac) metaflac --set-tag="BPM=$bpm" "$file" ;; 
        esac
    done

Bước 2.1 Xem lại Đây là tập lệnh sẽ thêm các thẻ BPM vào bộ sưu tập của bạn.

Nó chạy một tiến trình trên mỗi CPU Core để làm cho quá trình nhanh hơn. Ngoài ra, nó không sử dụng các tệp tạm thời và nó có khả năng phát hiện xem một tệp đã được gắn thẻ hay chưa.

Ngoài ra, tôi đã phát hiện ra rằng FLAC đôi khi có cả ID3 và VorbisVer bên trong. Kịch bản này cập nhật cả hai.

#!/bin/bash

function display_help() {
    cat <<-HELP
            Recursive BPM-writer for multicore CPUs.
            It analyzes BPMs of every media file and writes a correct tag there.
            Usage: $(basename "$0") path [...]
            HELP
    exit 0
    }

[ $# -lt 1 ] && display_help

#=== Requirements
requires="bpmcount mid3v2 vorbiscomment metaflac"
which $requires > /dev/null || { echo "E: These binaries are required: $requires" >&2 ; exit 1; }

#=== Functions

function bpm_read(){
    local file="$1"
    local ext="${file##*.}"
    declare -l ext
    # Detect
    { case "$ext" in
        'mp3')  mid3v2 -l "$file" ;;
        'ogg')  vorbiscomment -l "$file" ;;
        'flac') metaflac --export-tags-to=- "$file" ;;
        esac ; } | fgrep 'BPM=' | cut -d'=' -f2
    }
function bpm_write(){
    local file="$1"
    local bpm="${2%%.*}"
    local ext="${file##*.}"
    declare -l ext
    echo "BPM=$bpm @$file"
    # Write
    case "$ext" in
        'mp3')  mid3v2 --TBPM "$bpm" "$file" ;;
        'ogg')  vorbiscomment -a -t "BPM=$bpm" "$file" ;;
        'flac') metaflac --set-tag="BPM=$bpm" "$file"
                mid3v2 --TBPM "$bpm" "$file" # Need to store to ID3 as well :(
                ;;
        esac
    }

#=== Process
function oneThread(){
    local file="$1"
    #=== Check whether there's an existing BPM
        local bpm=$(bpm_read "$file")
        [ "$bpm" != '' ] && return 0 # there's a nonempty BPM tag
    #=== Detect a new BPM
    # Detect a new bpm
    local bpm=$(bpmcount "$file" | grep '^[0-9]' | cut -f1)
    [ "$bpm" == '' ] && { echo "W: Invalid BPM '$bpm' detected @ $file" >&2 ; return 0 ; } # problems
    # Write it
    bpm_write "$file" "${bpm%%.*}" >/dev/null
    }

NUMCPU="$(grep ^processor /proc/cpuinfo | wc -l)"
find $@ -type f -regextype posix-awk -iregex '.*\.(mp3|ogg|flac)' \
    | while read file ; do
        [ `jobs -p | wc -l` -ge $NUMCPU ] && wait
        echo "$file"
        oneThread "$file" &
        done

Thưởng thức! :)


Xuất sắc! Tôi đã không đi xung quanh để thử điều này tối qua. Theo như gắn thẻ dòng lệnh, hãy thử mid3v2: linux.die.net/man/1/mid3v2 , có thể sử dụng ít nhất cho đến khi Ex Falso hỗ trợ chỉnh sửa dòng lệnh. Id id3v2 tad làTBPM
DaveParillo

1
Cảm ơn, tôi sẽ thử trong vài ngày và đăng kết quả :) Tôi tự hỏi liệu FLAC có hỗ trợ điều đó không: tôi sẽ phải kiểm tra điều này.
kolypto

1
Làm việc tốt ở bước # 2. Chúc tôi có thể upvote hai lần!
DaveParillo

1
Cảm ơn :) Than ôi, Amarok của tôi đã không nhận thấy thẻ mới trong FLAC mà tôi thích nhất :)) đã gửi.
kolypto

Làm thế nào mà bạn cài đặt nó? vòng / phút họ cung cấp dường như không hoạt động trong máy tính của tôi và tôi đang vật lộn với việc biên dịch.
pedrosaurio


6

Tôi đã sử dụng tập lệnh gốc của kolypto bằng cách sử dụng bpmcountvà viết lại nó cho bpm-tag(tiện ích của bpm-tools) mà tôi đã may mắn hơn khi cài đặt. Tôi cũng đã thực hiện một số cải tiến của riêng tôi.

Bạn có thể tìm thấy nó trên GitHub https://github.com/meridius/bpmwrap


Điều này đòi hỏi một vài sửa đổi để hoạt động trên máy Mac, mà tôi đã đưa vào câu trả lời của riêng mình bên dưới (vì quá dài cho một nhận xét)
Adrian

2

Tôi không biết về một công cụ thực hiện chính xác những gì bạn đang tìm kiếm, nhưng tôi đã chơi xung quanh với MusicIP .

Đã sử dụng phiên bản linux / java - phải mất một thời gian dài để phân tích hoàn toàn một thư viện nhạc, nhưng nó thực sự hoạt động. Bạn có thể tìm thấy các bài hát tương tự như các bài hát khác. Bạn có thể nhấp chuột phải vào danh sách phát được tạo và chọn tùy chọn để chọn nhiều hoặc ít bài hát như bài hát đã chọn. Bạn cũng có thể chọn để loại bỏ một số thể loại. Thật tuyệt, nhưng sau khi yếu tố wow biến mất, tôi đã ngừng sử dụng nó.

Phiên bản miễn phí xuất danh sách phát lên tới 75 bài hát ở định dạng (ít nhất) m3u.

Hiện tại nó không được hỗ trợ, nhưng tôi nghĩ họ đã cố gắng mang nó thương mại như là Predexis .


1

Mặc dù nó không chỉ là một công cụ như bạn nói bạn đang tìm kiếm, trình phát phương tiện Banshee có thể phát hiện ra bpm.

Tôi sử dụng Banshee cho tất cả các hoạt động chơi nhạc, tổ chức và đồng bộ hóa với các trình phát di động. Tôi không liên kết, nhưng tôi thích chương trình tốt nhất trong tất cả những gì tôi đã thử. Nó cũng có thể tạo ra "danh sách phát thông minh" dựa trên tất cả các loại thuộc tính của các bản nhạc, bao gồm cả bpm.

Có một phần mở rộng phân tích tất cả các loại về bài hát và sẽ tìm thấy các bài hát tương tự với bài bạn đang chơi. Nó được gọi là Mirage và tôi đã sử dụng nó trong một thời gian, nhưng tôi không còn nữa, vì tôi đã tạo ra một số danh sách nhạc phù hợp với nhiều tâm trạng khác nhau (không nhất thiết phải giống với Mirage).

Tôi không biết nếu Banshee sẽ lưu bpm mà nó đã phát hiện trở lại vào thẻ "bpm" ID3v2 của tệp. Nếu ai biết cách dễ dàng kiểm tra thẻ bpm từ bên ngoài chương trình, tôi sẽ kiểm tra.



0

Tôi tìm thấy một công cụ khác để gắn thẻ các tệp MP3 có giá trị BPM chính xác.

Nó được gọi là BPMDetect . Mã nguồn mở. QT libs hoạt động tốt dưới Gnome. Đi kèm với GUI nhưng có thể được biên dịch thành phiên bản chỉ dành cho bảng điều khiển (chạy "scons console = 1" như đã nêu trong readme.txt).

Mặt khác, cuối cùng, tôi cũng đã sử dụng "bpmcount" từ BpmDJ vì tôi gặp khó khăn khi biên dịch BPMDetect trên máy chủ Ubuntu 64 bit (do phụ thuộc vào fmodex). Vì vậy, tôi đã lấy tập lệnh shell (rất hay và được viết tốt) ở trên (xem bên dưới), tệp nhị phân "bpmcount" được trích xuất từ ​​[x64 .rpm] [3] có sẵn trên trang web BpmDJ (tôi vừa trích xuất .rpm với

pm2cpio bpmdj-4.2.pl2-0.x86_64.rpm|cpio -idv

và nó làm việc như một lá bùa. Tôi chỉ phải sửa đổi tập lệnh trên vì, ngoài hộp, nó không hoạt động về phía tôi (vấn đề với thiết bị xuất chuẩn / stderr của nhị phân bpmcount). Sửa đổi của tôi là về chuyển hướng tập tin:

local bpm=$(bpmcount "$file" 3>&1 1>/dev/null 2>&3 | grep '^[0-9]' | cut -f1)

0

Có một công cụ khác được đề xuất trong câu hỏi này trên stackoverflow: aubio , đi kèm với các mô-đun python.

Tôi đã không thử nó vì tôi bận rộn với việc biên dịch BpmDj . Chỉ trong trường hợp bất kỳ ai khác thấy mình phải vật lộn với những rắc rối tương tự trong khi thử, tôi muốn khuyến nghị mạnh mẽ để đảm bảo chắc chắn:

  1. đã tải xuống bản phát hành mới nhất của các nguồn BpmDj
  2. cài đặt các thư viện boost thích hợp

Với các nâng cấp trình biên dịch g ++ mới nhất, một số vấn đề dường như đã phát sinh đặc biệt liên quan đến các bản phát hành debian và ub Ubuntu gần đây. Ngay khi nhận thức được những vấn đề này, tác giả đã có lòng tốt để khắc phục sự không tương thích nổi bật và đưa ra một bản phát hành mới mà bây giờ biên dịch như một lá bùa. Vì vậy, bất cứ ai đã gần rơi vào tuyệt vọng về lỗi biên dịch không ngừng gần đây: bạn đang lưu ngay bây giờ.

@ mmx , công cụ của bạn trông cũng tốt, nhưng chúng dựa vào SoX, mặc định không có tính năng mp3. Vì vậy, họ yêu cầu biên dịch SoX với hỗ trợ Lame / MAD trước tiên, điều không may là quá nhiều nỗ lực cho những người lười biếng như tôi.


0

Để giải pháp của @meridius hoạt động trên máy Mac của tôi, tôi đã phải thực hiện thêm một chút công việc và sửa đổi tập lệnh một chút:

# Let's install bpm-tools
git clone http://www.pogo.org.uk/~mark/bpm-tools.git
cd bpm-tools
make && make install
# There will be errors, but they did not affect the result

# The following three lines could be replaced by including this directory in your $PATH
ln -s <absolute path to bpm-tools>/bpm /usr/local/bin/bpm
ln -s <absolute path to bpm-tools>/bpm-tag /usr/local/bin/bpm-tag
ln -s <absolute path to bpm-tools>/bpm-graph /usr/local/bin/bpm-graph
cd ..

# Time to install a bunch of GNU tools
# Not all of these packages are strictly necessary for this script, but I decided I wanted the whole GNU toolchain in order to avoid this song-and-dance in the future
brew install coreutils findutils gnu-tar gnu-sed gawk gnutls gnu-indent gnu-getopt bash flac vorbis-tools
brew tap homebrew/dupes; brew install grep

# Now for Mutagen (contains mid3v2)
git clone https://github.com/nex3/mutagen.git
cd mutagen
./setup.py build
sudo ./setup.py install
# There will be errors, but they did not affect the result
cd ..

Sau đó, tôi đã phải sửa đổi tập lệnh để trỏ đến các phiên bản GNU của mọi thứ và một vài điều chỉnh khác:

#!/usr/local/bin/bash

# ================================= FUNCTIONS =================================

function help() {
    less <<< 'BPMWRAP

Description:
    This BASH script is a wrapper for bpm-tag utility of bpm-tools and several
    audio tagging utilities. The purpose is to make BPM (beats per minute)
    tagging as easy as possible.
    Default behaviour is to look through working directory for *.mp3 files
    and compute and print their BPM in the following manner:
        [current (if any)] [computed] [filename]

Usage:
    bpmwrap [options] [directory or filenames]

Options:
    You can specify files to process by one of these ways:
        1) state files and/or directories containing them after options
        2) specify --import file
        3) specify --input file
    With either way you still can filter the resulting list using --type option(s).
    Remember that the script will process only mp3 files by default, unless
    specified otherwise!

    -i, --import file
        Use this option to set BPM tag for all files in given file instead of
        computing it. Expected format of every row is BPM number and absolute path
        to filename separated by semicolon like so:
            145;/home/trinity/music/Apocalyptica/07 beyond time.mp3
        Remember to use --write option too.
    -n, --input file
        Use this option to give the script list of FILES to process INSTEAD of paths
        where to look for them. Each row whould have one absolute path.
        This will bypass the searching part and is that way useful when you want
        to process large number of files several times. Like when you are not yet
        sure what BPM limits to set. Extension filtering will still work.
    -o, --output file
        Save output also to a file.
    -l, --list-save file
        Save list of files about to get processed. You can use this list later
        as a file for --input option.
    -t, --type filetype
        Extension of file type to work with. Defaults to mp3. Can be specified
        multiple times for more filetypes. Currently supported are mp3 ogg flac.
    -e, --existing-only
        Only show BPM for files that have it. Do NOT compute new one.
    -w, --write
        Write computed BPM to audio file but do NOT overwrite existing value.
    -f, --force
        Write computed BPM to audio file even if it already has one. Aplicable only
        with --write option.
    -m, --min minbpm
        Set minimal BPM to look for when computing. Defaults to bpm-tag minimum 84.
    -x, --max maxbpm
        Set maximal BPM to look for when computing. Defaults to bpm-tag maximum 146.
    -v, --verbose
        Show "progress" messages.
    -c, --csv-friendly
        Use semicolon (;) instead of space to separate output columns.
    -h, --help
        Show this help.

Note:
    Program bpm-tag (on whis is this script based) is looking only for lowercase
    file extensions. If you get 0 (zero) BPM, this should be the case. So just
    rename the file.

License:
    GPL V2

Links:
    bpm-tools (http://www.pogo.org.uk/~mark/bpm-tools/)

Dependencies:
    bpm-tag mid3v2 vorbiscomment metaflac

Author:
    Martin Lukeš (martin.meridius@gmail.com)
    Based on work of kolypto (http://superuser.com/a/129157/137326)
    '
}

# Usage: result=$(inArray $needle haystack[@])
# @param string needle
# @param array haystack
# @returns int (1 = NOT / 0 = IS) in array
function inArray() {
    needle="$1"
    haystack=("${!2}")
    out=1
    for e in "${haystack[@]}" ; do
        if [[ "$e" = "$needle" ]] ; then
            out=0
            break
        fi
    done
    echo $out
}

# Usage: result=$(implode $separator array[@])
# @param char separator
# @param array array to implode
# @returns string separated array elements
function implode() {
    separator="$1"
    array=("${!2}")
    IFSORIG=$IFS
    IFS="$separator"
    echo "${array[*]}"
    IFS=$IFSORIG
}

# @param string file
# @returns int BPM value
function getBpm() {
    local file="$1"
    local ext="${file##*.}"
    declare -l ext # convert to lowercase
    { case "$ext" in
        'mp3')  mid3v2 -l "$file" ;;
        'ogg')  vorbiscomment -l "$file" ;;
        'flac') metaflac --export-tags-to=- "$file" ;;
    esac ; } | fgrep 'BPM=' -a | cut -d'=' -f2
}

# @param string file
# @param int BPM value
function setBpm() {
    local file="$1"
    local bpm="${2%%.*}"
    local ext="${file##*.}"
    declare -l ext # convert to lowercase
    case "$ext" in
        'mp3')  mid3v2 --TBPM "$bpm" "$file" ;;
        'ogg')  vorbiscomment -a -t "BPM=$bpm" "$file" ;;
        'flac') metaflac --set-tag="BPM=$bpm" "$file"
            mid3v2 --TBPM "$bpm" "$file" # Need to store to ID3 as well :(
        ;;
    esac
}

# # @param string file
# # @returns int BPM value
function computeBpm() {
    local file="$1"
    local m_opt=""
    [ ! -z "$m" ] && m_opt="-m $m"
    local x_opt=""
    [ ! -z "$x" ] && x_opt="-x $x"
    local row=$(bpm-tag -fn $m_opt $x_opt "$file" 2>&1 | fgrep "$file")
    echo $(echo "$row" \
        | gsed -r 's/.+ ([0-9]+\.[0-9]{3}) BPM/\1/' \
        | gawk '{printf("%.0f\n", $1)}')
}

# @param string file
# @param int file number
# @param int BPM from file list given by --import option
function oneThread() {
    local file="$1"
    local filenumber="$2"
    local bpm_hard="$3"
    local bpm_old=$(getBpm "$file")
    [ -z "$bpm_old" ] && bpm_old="NONE"
    if [ "$e" ] ; then # only show existing
        myEcho "$filenumber/$NUMFILES${SEP}$bpm_old${SEP}$file"
    else # compute new one
        if [ "$bpm_hard" ] ; then
            local bpm_new="$bpm_hard"
        else
            local bpm_new=$(computeBpm "$file")
        fi
        [ "$w" ] && { # write new one
            if [[ ! ( ("$bpm_old" != "NONE") && ( -z "$f" ) ) ]] ; then
                setBpm "$file" "$bpm_new"
            else
                [ "$v" ] && myEcho "Non-empty old BPM value, skipping ..."
            fi
        }
        myEcho "$filenumber/$NUMFILES${SEP}$bpm_old${SEP}$bpm_new${SEP}$file"
    fi
}

function myEcho() {
    [ "$o" ] && echo -e "$1" >> "$o"
    echo -e "$1"
}


# ================================== OPTIONS ==================================

eval set -- $(/usr/local/Cellar/gnu-getopt/1.1.6/bin/getopt -n $0 -o "-i:n:o:l:t:ewfm:x:vch" \
    -l "import:,input:,output:,list-save:,type:,existing-only,write,force,min:,max:,verbose,csv-friendly,help" -- "$@")

declare i n o l t e w f m x v c h
declare -a INPUTFILES
declare -a INPUTTYPES
while [ $# -gt 0 ] ; do
    case "$1" in
        -i|--import)                shift ; i="$1" ; shift ;;
        -n|--input)                 shift ; n="$1" ; shift ;;
        -o|--output)                shift ; o="$1" ; shift ;;
        -l|--list-save)         shift ; l="$1" ; shift ;;
        -t|--type)                  shift ; INPUTTYPES=("${INPUTTYPES[@]}" "$1") ; shift ;;
        -e|--existing-only) e=1 ; shift ;;
        -w|--write)                 w=1 ; shift ;;
        -f|--force)                 f=1 ; shift ;;
        -m|--min)                       shift ; m="$1" ; shift ;;
        -x|--max)                       shift ; x="$1" ; shift ;;
        -v|--verbose)               v=1 ; shift ;;
        -c|--csv-friendly)  c=1 ; shift ;;
        -h|--help)                  h=1 ; shift ;;
        --)                                 shift ;;
        -*)                                 echo "bad option '$1'" ; exit 1 ;; #FIXME why this exit isn't fired?
        *)                                  INPUTFILES=("${INPUTFILES[@]}" "$1") ; shift ;;
    esac
done


# ================================= DEFAULTS ==================================

#NOTE Remove what requisities you don't need but don't try to use them after!
#         always  mp3/flac     ogg       flac
REQUIRES="bpm-tag mid3v2 vorbiscomment metaflac"
which $REQUIRES > /dev/null || { myEcho "These binaries are required: $REQUIRES" >&2 ; exit 1; }

[ "$h" ] && {
    help
    exit 0
}

[[ $m && $x && ( $m -ge $x ) ]] && {
    myEcho "Minimal BPM can't be bigger than NOR same as maximal BPM!"
    exit 1
}
[[ "$i" && "$n" ]] && {
    echo "You cannot specify both -i and -n options!"
    exit 1
}
[[ "$i" && ( "$m" || "$x" ) ]] && {
    echo "You cannot use -m nor -x option with -i option!"
    exit 1
}
[ "$e" ] && {
    [[ "$w" || "$f" ]] && {
        echo "With -e option you don't have any value to write!"
        exit 1
    }
    [[ "$m" || "$x" ]] && {
        echo "With -e option you don't have any value to count!"
        exit 1
    }
}

for file in "$o" "$l" ; do
    if [ -f "$file" ] ; then
        while true ; do
            read -n1 -p "Do you want to overwrite existing file ${file}? (Y/n): " key
            case "$key" in
                y|Y|"") echo "" > "$file" ; break ;;
                n|N)        exit 0 ;;
            esac
            echo ""
        done
        echo ""
    fi
done

[ ${#INPUTTYPES} -eq 0 ] && INPUTTYPES=("mp3")

# NUMCPU="$(ggrep ^processor /proc/cpuinfo | wc -l)"
NUMCPU="$(sysctl -a | ggrep machdep.cpu.core_count | gsed -r 's/(.*)([0-9]+)(.*)/\2/')"
LASTPID=0
TYPESALLOWED=("mp3" "ogg" "flac")
# declare -A BPMIMPORT # array of BPMs from --import file, keys are file names
declare -A BPMIMPORT # array of BPMs from --import file, keys are file names

for type in "${INPUTTYPES[@]}" ; do
    [[ $(inArray $type TYPESALLOWED[@]) -eq 1 ]] && {
        myEcho "Filetype $type is not one of allowed types (${TYPESALLOWED[@]})!"
        exit 1
    }
done

### here are three ways how to pass files to the script...
if [ "$i" ] ; then # just parse given file list and set BPM to listed files
    if [ -f "$i" ] ; then
        # myEcho "Setting BPM tags from given file ..."
        while read row ; do
            bpm="${row%%;*}"
            file="${row#*;}"
            ext="${file##*.}"
            ext="${ext,,}" # convert to lowercase
            if [ -f "$file" ] ; then
                if [ $(inArray $ext INPUTTYPES[@]) -eq 0 ] ; then
                    FILES=("${FILES[@]}" "$file")
                    BPMIMPORT["$file"]="$bpm"
                else
                    myEcho "Skipping file on row $rownumber (unwanted filetype $ext) ... $file"
                fi
            else
                myEcho "Skipping non-existing file $file"
            fi
        done < "$i"
    else
        myEcho "Given import file does not exists!"
        exit 1
    fi
elif [ "$n" ] ; then # get files from file list
    if [ -f "$n" ] ; then
        rownumber=1
        while read file ; do
            if [ -f "$file" ] ; then
                ext="${file##*.}"
                ext="${ext,,}" # convert to lowercase
                if [ $(inArray $ext INPUTTYPES[@]) -eq 0 ] ; then
                    FILES=("${FILES[@]}" "$file")
                else
                    myEcho "Skipping file on row $rownumber (unwanted filetype $ext) ... $file"
                fi
            else
                myEcho "Skipping file on row $rownumber (non-existing) ... $file"
            fi
            let rownumber++
        done < "$n"
        unset rownumber
    else
        myEcho "Given input file $n does not exists!"
        exit 1
    fi
else # get files from given parameters
    [ ${#INPUTFILES[@]} -eq 0 ] && INPUTFILES=`pwd`
    for file in "${INPUTFILES[@]}" ; do
        [ ! -e "$file" ] && {
            myEcho "File or directory $file does not exist!"
            exit 1
        }
    done
    impl_types=`implode "|" INPUTTYPES[@]`
    while read file ; do
        echo -ne "Creating list of files ... (${#FILES[@]}) ${file}\033[0K"\\r
        FILES=("${FILES[@]}" "$file")
    done < <(gfind "${INPUTFILES[@]}" -type f -regextype posix-awk -iregex ".*\.($impl_types)")
    echo -e "Counted ${#FILES[@]} files\033[0K"\\r
fi

[ "$l" ] && printf '%s\n' "${FILES[@]}" > "$l"

NUMFILES=${#FILES[@]}
FILENUMBER=1

[ $NUMFILES -eq 0 ] && {
    myEcho "There are no ${INPUTTYPES[@]} files in given files/paths."
    exit 1
}

declare SEP=" "
[ "$c" ] && SEP=";"


# =============================== MAIN SECTION ================================

if [ "$e" ] ; then # what heading to show
    myEcho "num${SEP}old${SEP}filename"
else
    myEcho "num${SEP}old${SEP}new${SEP}filename"
fi

for file in "${FILES[@]}" ; do
    [ `jobs -p | wc -l` -ge $NUMCPU ] && wait
    [ "$v" ] && myEcho "Parsing (${FILENUMBER}/${NUMFILES})\t$file ..."
    oneThread "$file" "$FILENUMBER" "${BPMIMPORT[$file]}" &
    LASTPID="$!"
    let FILENUMBER++
done

[ "$v" ] && myEcho "Waiting for last process ..."
wait $LASTPID
[ "$v" ] && myEcho \\n"DONE"

Cảm ơn bạn đã làm việc chăm chỉ @kolypto và @meridius.

... nỗi đau tôi trải qua để duy trì quy trình làm việc CLI và không phải trả tiền cho các công cụ âm nhạc ...

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.