Premiär! Fyndchans i SweClockers Månadens Drop

Hur spara filnamn i variabel el. dyl?

Permalänk
Medlem

Hur spara filnamn i variabel el. dyl?

Behöver skapa en enkel funktion där en ljudfil (wav/aif) processas av friliggande .exe och sen sparas som MP3 i samma mapp.
Har gjort det här genom vanlig CMD. Jag anropar .EXE-n via ett BAT-script (eller powershell-script) och säger åt EXEn att processa alla filer i mappen av typen wav/aif, och spara som "File.mp3".

Problemet jag vill lösa är att så fort flera ljudfiler ska processas, så sparas alla som "File.mp3", dvs nästkommande fil skriver över första "File.mp3". Den ena skriver över den andra osv.
Jag tänker att jag behöver kunna kopiera filnamnet (på wav/aif-filen) och lagra den infon i typ nån variabel eller liknande, för att sen - när filen ska sparas - ange att filen ska sparas som "%Variabel-värde%.mp3" typ. Då kommer alla MP3-filer sparas med samma filnamn som den WAV/AIF fil dom är baserade på.

Men det verkar inte finnas nåt enda sätt för BAT-filer eller Powershell script att läsa av filnamn och spara datan på nåt temporärt sätt(?)

Finns här någon som kan känna till en lösning eller tips för att lösa det här problemet?
Eller, sitter man kanske fast i björnsaxen för att man valt fel/dålig lösning till att lösa den här uppgiften?

Tips, hjälp eller kommentarer välkomna
/T

Visa signatur

Jag använder datorn för att göra jobb bättre, inte för att jobba med att göra datorn bättre

Permalänk
Medlem

Kika lite på get-childitem i PowerShell. Kommandot kan läsa av filnamn och jag vill minnas att det sparas i någon form av variabel också (kan vara $_.name).

https://technet.microsoft.com/en-us/library/hh849800.aspx
http://blogs.technet.com/b/heyscriptingguy/archive/2013/11/22...
https://technet.microsoft.com/en-us/library/ee692796.aspx

Permalänk
Legendarisk

@TomKe: Vad är det för program du använder för konverteringen och hur ser dess interface ut (in-/utparametrar)? Om det endast konverterar alla filer i en mapp så skulle du kunna göra ett script som flyttar in en fil åt gången, startar konverteringen, och sedan hämtar ut och byter namn på utfilen, men det låter underligt...

Är det verkligen nödvändigt så skulle du kunna lösa det ungefär så här:

# # Get-ChildItem låter dig hitta alla filer du är intresserad av att # konvertera, du pipar sedan listan till ForEach-Object (här används # aliaset %) och hanterar filerna en och en: # Get-ChildItem -Path ./in -Filter *.wav | %{ # # Inuti scriptblocket representerar den automatiskt skapade # variablen $_ din aktuella fil: # # Egenskap | Exempelvärde # -------------+-------------------------- # $_.FullName | C:/Path/To/File.wav # $_.Name | File.wav # $_.BaseName | File # $InFile = $_.FullName $TempFile = "./convert/{0}" -f $_.Name $OutFile = "./out/{0}.mp3" -f $_.BaseName Copy-Item $InFile $TempFile Convert-Dummy ./convert Move-Item ./convert/File.mp3 $OutFile Remove-Item $TempFile }

Visa signatur

Abstractions all the way down.

Permalänk
Medlem

@Tunnelsork: You read my mind

Get-childitem – som jag får tacka @Zakire för^^ - verkade funka rätt bra. Är det bara 1 ljudfil i mappen går allt bra. Men är det flera filer (= flera filnamn som ska sparas i variabel) så sparades följande i variabeln "Filnamn1Filnamn2Filnamn3". Inte så smidigt.

Måste försöka få till en slinga tror ja Precis som du föreslår. Det såg ut som en lösning värd att titta på. Den är på gränsen till överkurs för mig, men jag hänger på rätt bra ändå.

Hela idén är att få iväg en enkel o processad ljudfil till en anna person - ev. uppladdad på nån server - så snabbt som det nånsin bara går, och automatiskt. Är inte så haj på scripting/programmering men hankar mig fram så gott man kan.

Vill alltså processa wav/aif-fil: göra 0,5 sek fade in och fade out, samt "normalisera" (höja volymen i filen, så högsta ljudnivån når upp i taket) och göra om filen till 44100hz 16bit (CD-kvalitet). Slutligen koda den som MP3 och skicka iväg den – automatiskt.
Min egna bästa lösning har blivit att spara ner wav/aif-filerna i en och samma mapp, för att underlätta sökning (*.wav/aif) samt processning osv.

Jag använder programmet "Sox" för att göra fade in/out, greja volym och annat. Sox ligger som en fri exe-fil i mappen. Konverteringen till MP3 kör jag genom Lame, ligger också som friliggande exe-fil i samma mapp.
Jag har hittills skickat parametrar till dessa två program via BAT-fil och det funkar - förutom just det där med att kopiera filnamnet då. Parametrarna ser ut såhär:

cd\ cd H:\Render_Folder Sox.exe *.wav -b 16 -r 44100 -c 2 --norm --no-clobber -S file.wav highpass 10 fade h 4 0 6 Lame.exe -m simple --noreplaygain -v -t -p file.wav file.mp3 del file.wav move *.wav /konverterat move *.mp3 "F:\MP3-mapp" CLS echo ”Det fuckin’ funkar. Jag är ett geni!!” pause

Sox processar alla *.wav-filer i mappen och sparar resultatet som ”file.wav”. Sen kommer Lame och processar alla filer som heter ”file.wav” till ”file.mp3”.
När en fil processats så är tanken att radera eller flytta den från mappen (med Powershell). På så sätt kan man använda *.wav/aif som sök-kriterium i mappen utan att få med alla gamla filer som redan processats.

Kanske finns bättre script-lösningar för det här, men jag har inte hittat nåt program som gör allt detta åt en. Det är just det där med processningen av ljudfiler som är kruxet. Ska kika på ditt förslag

Visa signatur

Jag använder datorn för att göra jobb bättre, inte för att jobba med att göra datorn bättre

Permalänk
Medlem

Hmm... Jag tänker mig att du delar upp filerna i tre mappar, en som sox.exe ska härja i, en som lame.exe ska härja i och en som innehåller färdiga filer.

Du bygger sedan två script som innehåller get-childitem och foreach. Dvs. script 1 går igenom alla filer den hittar i katalog 1 och konverterar de till wav-filer med sox.exe och flyttar över de en och en till katalog 2. Script 2 går sedan igenom alla filer i katalog 2 och kör sitt race med lame.exe och slutligen flyttar de till en tredje katalog som då bara innehåller färdiga filer.

Typ så här:

Script 1
För varje item i katalog 1
--> Konvertera med sox.exe
--> Flytta till katalog 2

Script 2
För varje item i katalog 2
--> Modifiera med lame.exe
--> Flytta till katalog 3

Permalänk
Medlem

Tror jag är nåt relativt bra på spåren ändå faktiskt

$Filnamn = Get-ChildItem *.wav | ForEach-Object {&'h:\render_folder\lame.exe' --noreplaygain,-v,-t,-p,$Filnamn.wav,$Filnamn.mp3,--nohist,-m,s}

Fast nu uppstår ju problemet att $Filnamn.* inte godtas av lame.exe, och verkar inte heller tolkas som referens till variabel av Powershell, eftersom det står angivet bland parametrarna man skickar till lame.exe. Antar att det är mest en fråga om formulering? Eller placering? ... för att få powershell att fylla i filnamnet innan parametrarna skickas till lame.

Visa signatur

Jag använder datorn för att göra jobb bättre, inte för att jobba med att göra datorn bättre

Permalänk
Legendarisk

@TomKe: Strukturen för den där kodsnutten gör inte riktigt vad du förväntar dig. Det kanske blir tydligare att se vad som händer så här: $Resultat = (1,2,3) | %{ $_ * 2; }

Om du nu tittar på $Resultat så innehåller den en array med värdena (2,4,6) istället för värdena (1,2,3). Orsaken är att det tilldelats resultatet av hela pipelinen; varje gång ForEach-Object kör scriptblocket outputas en ny int, och alla sparas som en array i $Resultat. Samma sak händer med din kodsnutt, $Filnamn finns inte tillgänglig förrän hela pipelinen är avslutad, och även om den fungerade som jag misstänker att du avsett så hade den innehållit en lista med filer istället för det aktuella objektet. Kom ihåg att använda variablen $_ för att komma åt det.


Det här scriptet borde göra ungefär vad du vill. Det bygger kommandon för att konvertera varje wav-fil i $InputFolder med Sox/Lame enligt din mall ovan och sparar sedan resultatet i $OutputFolder.

$InputFolder = "./input" $TempFolder = "./convert" $OutputFolder = "./output" $SoxPath = "./bin/sox/sox.exe" $LamePath = "./bin/lame/lame.exe" Get-ChildItem -Path $InputFolder -Filter *.wav | %{ $InputName = $_.FullName $TempName = "{0}/{1}" -f $TempFolder, $_.Name $OutputName = "{0}/{1}.mp3" -f $OutputFolder, $_.BaseName $SoxCommand = "{0} '{1}' -b 16 -r 44100 -c 2 --norm --no-clobber -S '{2}' highpass 10 fade h 4 0 6" -f $SoxPath, $InputName, $TempName $LameCommand = "{0} -m simple --noreplaygain -v -t -p '{1}' '{2}'" -f $LamePath, $TempName, $OutputName Clear-Host "Processing {0}`n" -f $_.Name Invoke-Expression $SoxCommand "`n" Invoke-Expression $LameCommand Remove-Item $TempName }

Visa signatur

Abstractions all the way down.