Skip to content

Instantly share code, notes, and snippets.

@khannurien khannurien/fflthread.c
Last active May 6, 2019

Embed
What would you like to do?
Usage: find /path/to/flac/folder -name "*.flac" | xargs -d '\n' /path/to/fflthread
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
/**
* Structure de données partagée pour limiter le nombre de threads.
*/
struct mutex {
pthread_mutex_t mutex;
pthread_cond_t cond;
size_t nbWorkers;
size_t maxThreads;
};
struct mutex jobs;
/**
* Fonction d'appel à ffmpeg, passée aux threads.
* @param data Nom du fichier à transcoder.
*/
void * exec_ffmpeg(void * data) {
char * flacName;
char * fileName;
size_t nbChar = strlen(data);
// should I be working?
if (pthread_mutex_lock(&jobs.mutex) == EINVAL) return NULL;
while (jobs.nbWorkers > jobs.maxThreads) {
pthread_cond_wait(&jobs.cond, &jobs.mutex);
}
// yes I should
jobs.nbWorkers++;
if (pthread_mutex_unlock(&jobs.mutex) == EINVAL) return NULL;
// cleaned up flac name
flacName = (char *) malloc((nbChar + 1) * sizeof(char));
strncpy(flacName, data, nbChar);
flacName[nbChar] = '\0';
// nb chars in flac == mp3 + \0
fileName = (char *) malloc(nbChar * sizeof(char));
// remove "flac" + '\0'
strncpy(fileName, data, nbChar - 4);
// concatenate "mp3" and null terminate
strcat(fileName, "mp3");
// ffmpeg options
char ffmpeg[] = "ffmpeg -i \"";
char ffargs[] = "\" -y -acodec libmp3lame -ab 320k \"";
char ffsend[] = "\"";
// build command
char cmd[strlen(ffmpeg) + strlen(flacName) + strlen(ffargs) + strlen(fileName) + strlen(ffsend) + 1];
strncpy(cmd, ffmpeg, strlen(ffmpeg) + 1);
strncat(cmd, flacName, strlen(data) + 1);
strncat(cmd, ffargs, strlen(ffargs) + 1);
strncat(cmd, fileName, strlen(fileName) + 1);
strncat(cmd, ffsend, strlen(ffsend) + 1);
// exec command
if (system(cmd) == -1) {
perror("system");
exit(EXIT_FAILURE);
}
// remove flac file
if (remove(flacName) != 0) {
perror("remove");
exit(EXIT_FAILURE);
}
// end of job
if (pthread_mutex_lock(&jobs.mutex) == EINVAL) return NULL;
jobs.nbWorkers--;
pthread_cond_broadcast(&jobs.cond);
if (pthread_mutex_unlock(&jobs.mutex) == EINVAL) return NULL;
return(data);
}
/**
* Enjoy ffmpeg lame transcodes from flac to mp3 in full throttle mode
*/
int main(int argc, char * argv[]) {
int nbThreads = argc - 1;
pthread_t tid[nbThreads];
void * status[nbThreads];
int i;
// init nb threads
jobs.nbWorkers = 0;
jobs.maxThreads = 4;
// init mutex & cond
if (pthread_mutex_init(&jobs.mutex, NULL) == -1) {
perror("pthread_mutex_init");
exit(EXIT_FAILURE);
}
if (pthread_cond_init(&jobs.cond, NULL) == -1) {
perror("pthread_cond_init");
exit(EXIT_FAILURE);
}
// one thread per flac file
for (i = 0; i < nbThreads; i++) {
if (pthread_create(&tid[i], NULL, exec_ffmpeg, argv[i + 1]) != 0) {
perror("pthread_create");
exit(EXIT_FAILURE);
}
}
// wait for every transcode
for (i = 0; i < nbThreads; i++) {
if (pthread_join(tid[i], &status[i]) != 0) {
perror("pthread_join");
exit(EXIT_FAILURE);
}
}
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.