I have about 10,000 audio files that I need to overlay with copyright sound. How can this be done with ffmpeg? Maybe there is a script for mass combining audio into one track?
If there is a simpler solution, I will be very grateful, since several days of googling did not lead to anything. Either I found programs without a job description, or solutions that only do one file at a time.
You can write a script for that depending your operating system. As I program with php, I would write a php CLI programme for this use case
Something like:
#!/usr/bin/php
// ensure ./new directory exists before running script
<?php
$dir = "/home/seb/Audio samples/";
$files1 = scandir($dir); //Get all the file from your $dir directory on your computer
foreach ($files1 as $myfile){
$mystring = "ffmpeg -i $myfile ./new/$myfile"; //Write here your FFMPEG command you want in a string
exec($mystring);
}
?>
Related
I intend on making a cli audio player for racket, as an exercise to learn Racket, and everything else that would entail this project. I am stuck though how to begin. I can't find any package to play sound files, so I am guessing I may have to make one. How would I go about it?
What you probably want is #lang video (website). It provides a high level interface into audio playback. Allowing you to do something like:
#lang video
(clip "file.mp3")
Since you want to make a little command line player you might also want to take a look at its small preview tool.
I ended doing this the hackish way by calling a shell script via racket, not ideal at all. For reference, putting the code here.
; This creates the initail rsound
; for a song, this rsound is passed around
; so the whole song doesn't have to be
; decoded from the file everytime.
(define (play filepath)
(cond [(string=? "mp3" (last (regexp-split #rx"\\." filepath)))
(system* "./mp3-hack" filepath)
(set! filepath "curr.wav")])
(define input-pstream (make-pstream))
(define input-rsound (rs-read filepath))
(pstream-play input-pstream input-rsound)
(values input-pstream input-rsound filepath))
And the mp3-hack file just uses ffmpeg
#!/bin/sh
ffmpeg -i $1 -acodec pcm_s16le -ac 1 -ar 44100 curr.wav
Yeah, I know. Inelegant, but at least I got it working. I needed it for my hackathon project MPEGMafia
not sure about how to correctly title this, please change it if you prefer
given that my code actually works, I'd like to have a peer review to increase the quality of it.
I have a folder full of .zip files. Theese files are streams of data (identifiable by their stream name) daily offloaded. There could be more than one daily file per stream, so I need to grab the last one in order of time. I can't rely on posix timestamp for this, so files expose timestamp on their name.
Filename example:
XX_XXYYZZ_XYZ_05_AB00C901_T001_20170808210052_20170808210631.zip
Last two fields are timestamps, and I'm interested in the second-last.
other fields are useless (now)
I've previously stored the stream name (in this case XYZ_05_AB00C901_T001 in the variable $stream
I have this line of code:
match=$(ls "$streamPath"/*.zip|grep "$stream"|rev|cut -d'_' -f2|rev|sort|tail -1)
And what it does is to search the given path for files matching the stream, cutting out the timestamp and sorting them. So now that I know what is the last timestamp for this stream, I can ls again, this time grepping for $streamand $match togegher, and I'm done:
streamFile=$(ls "$streamPath"/.zip|grep "$stream.*$match\|$match.*$stream")
Question time:
Is there a better way to achieve my goal ? Probably more than one, I'll prefer one-liner solution, tough.
ShellChecks advices me that it would be better to use a for loop or a while cycle instead of ls, to be able to handle particular filenames (which I'm not facing ATM, but who knows), but I'm not so sure about it (seems more complicated to me).
Thanks.
O.
Thanks to the page suggested by Cyrus I chose to go with this solution:
echo "$file"|grep "$stream"|rev|cut -d'_' -f2|rev|sort|tail -1
done < <(find "$streamPath" -maxdepth 1 -type f -name '*.zip' -print0)
For example I want to download data from:
http://nimbus.cos.uidaho.edu/DATA/OBS/
with the link:
http://nimbus.cos.uidaho.edu/DATA/OBS/pr_1979.nc
to
http://nimbus.cos.uidaho.edu/DATA/OBS/pr_2015.nc
How can I write a script to download all of them? with wget?and how to loop the links from 1979 to 2015?
wget can take file as input which contains URLs per line.
wget -ci url_file
-i : input file
-c : resume functionality
So all you need to do is put the URLs in a file and use that file with wget.
A simple loop like Jeff Puckett II's answer will be sufficient for your particular case, but if you happen to deal with more complex situations (random urls), this method may come in handy.
Probably something like a for loop iterating over a predefined series.
Untested code:
for i in {1979..2015}; do
wget http://nimbus.cos.uidaho.edu/DATA/OBS/pr_$i.nc
done
I have basic knowledge of linux bash shell scripting, right now I am facing a problem that is like following:
Suppose I am working in an empty directory mydir
Then there is a process which is created by a C program to generate a file with one word. (Exp: file.txt would have one word, "hello")
Routinely, after a specific period of time, the file is updated by the C program with the same one word "hello".
I want check the file every time when it is updated.
But the issue is that I also want my script doing some other operation while checking the file updates and when it detects file updates that it returns something for which I can use to trigger something else.
So, can anyone help me.
Also, some proof of concept :
while true;
do
func1();
func2();
check file is updated or not
if updated ; then
break;
else
continue;
You probably want the stat command. Do man stat to see how yours works. You want to look for "modtime" or "time of last data modification" option. For mine that would be stat -c%Y file. Something like basemodtime=$(stat -c%Y file) before the loop, modtime=$(stat -c%Y file) after func2(), and then if [ $modtime != $basemodtime ]; then to detect "updated".
I'm using a serial device for a project, and what I'm trying to accomplish PC side, is listening for a command sent by the serial device, interpreting the query, running some code depending on the query, and transmitting back the result.
To be honest I tried out using PHP as the listener, and it works, unfortunately the infinite loop required to make the script act as a receiver, loads the CPU to 25%. So it's not really the best option.
I'm using cygwin right now, I'd like to create a bash script using linux native commands.
I can receive data by using:
cat /dev/ttyS2
And send a response with:
echo "command to send" > /dev/ttyS2
My question is, how do I make an automated listener to be able to receive and send data? The main issue I have, is actually how do I stop the cat /dev/ttyS2 command once information was received, put it into a variable which then I could compare with a switch, or a series of if else then blocks. Afterwards send back a response and start the cycle all over again?
Thanks
Is this not what you're looking for?
while read -r line < /dev/ttyS2; do
# $line is the line read, do something with it
# which produces $result
echo $result > /dev/ttyS2
done
It's possible that reopening the serial device on every line has some side-effect, in which case you could try:
while read -r line; do
# $line is the line read, do something with it
# which produces $result
echo $result > /dev/ttyS2
done < /dev/ttyS2
You could also move the output redirection, but I suspect you will have to turn off stdout buffering.
To remain fairly system independent, use a cross platform programming language: like Python, use a cross platform serial library like : pySerial and do the processing inside a script. I have used pySerial and I could run the script cross platform with almost no changes in source code. By using BASH you're limiting yourself a fair little.
If you use right tools, it is possible to actually have your CPU usage to be exactly 0 when your device does not have any output.
To accomplish this, you should use some higher level language (Perl, Python, C/C++ would do, but not bash) and use select loop on top of file handle of your serial device. This is an example for Perl http://perldoc.perl.org/IO/Select.html, but you can use any other language as long as it has support for select() syscall.
I would recommend to use C/C++ with Qt 5.1.1, it's really easy and if you are familiar with the framework it'll be a piece of cake!!!
Here you can find more information and here more helpful examples, give it a try,
it's really pain free!! Also you can develop on win and then port your code to linux...straight forward.
Declare an object like this:
QSerialPort mPort; //remember to #include <QtSerialPort/QSerialPort>
//also add QT += serialport to your .pro file
Then add this code:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
setupUi(this);
connect(this->pushButton,SIGNAL(clicked()),this,SLOT(sendData()));
mPort.setPortName("ttyS0");
mPort.setBaudRate(QSerialPort::Baud115200);
mPort.setParity(QSerialPort::EvenParity);
if(!mPort.open(QSerialPort::ReadWrite))
{
this->label->setText(tr("unable to open port, %1").arg(mPort.error()));
}
connect(&(this->mPort),SIGNAL(readyRead()),this,SLOT(readData()));
}
void MainWindow::sendData()
{
QByteArray data = lineEdit->text().toLatin1();
if(mPort.isOpen())
{
mPort.write(data);
}
else
{
this->label->setText(tr("port closed %1").arg( mPort.error()));
}
}
void MainWindow::readData()
{
QString newData;
int bread=0;
while(bread < mPort.bytesAvailable() ){
newData += mPort.readAll();
bread++;
}
this->textEdit->insertPlainText("\n" + newData);
}