second commit
This commit is contained in:
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
# Xmake cache
|
||||
.xmake/
|
||||
build/
|
||||
|
||||
# MacOS Cache
|
||||
.DS_Store
|
||||
|
||||
|
||||
.vscode
|
||||
@@ -17,3 +17,18 @@
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
<!--
|
||||
|
||||
|
||||
Prendre un fichier midi :
|
||||
|
||||
- Sélectionner un passage
|
||||
- Sélectionner les instruments
|
||||
- Générer les fichiers midi
|
||||
|
||||
|
||||
|
||||
|
||||
-->
|
||||
|
||||
48
src/main.cpp
Normal file
48
src/main.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#include "stx-execpipe.h"
|
||||
#include <iostream>
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
static const std::vector<std::string> links = {
|
||||
"2gQ--SCEfmI"};
|
||||
|
||||
static const std::string YTDLP_BINARY = "/usr/bin/yt-dlp";
|
||||
|
||||
void DownloadFile()
|
||||
{
|
||||
stx::ExecPipe ep;
|
||||
|
||||
std::string link = "https://music.youtube.com/watch?v=" + links.front();
|
||||
|
||||
std::vector<std::string> args = {YTDLP_BINARY, link.c_str(), "--extract-audio", "--audio-format", "vorbis", "-o", "%(id)s.%(ext)s"};
|
||||
|
||||
ep.add_exec(&args);
|
||||
ep.run();
|
||||
}
|
||||
|
||||
float GetDuration()
|
||||
{
|
||||
stx::ExecPipe ep;
|
||||
|
||||
std::string fileName = links.front() + ".ogg";
|
||||
|
||||
std::vector<std::string> args = {"/usr/bin/ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", fileName};
|
||||
|
||||
ep.add_exec(&args);
|
||||
std::string output;
|
||||
ep.set_output_string(&output);
|
||||
ep.run();
|
||||
|
||||
return std::stof(output);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
float duration = GetDuration();
|
||||
|
||||
std::cout << "Durée : " << duration << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
1698
src/stx-execpipe.cpp
Normal file
1698
src/stx-execpipe.cpp
Normal file
File diff suppressed because it is too large
Load Diff
367
src/stx-execpipe.h
Normal file
367
src/stx-execpipe.h
Normal file
@@ -0,0 +1,367 @@
|
||||
// -*- mode: c++; fill-column: 79 -*-
|
||||
|
||||
/*
|
||||
* STX Execution Pipe Library v0.7.0
|
||||
* Copyright (C) 2010 Timo Bingmann
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU Lesser General Public License as published by the
|
||||
* Free Software Foundation; either version 2.1 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _STX_EXECPIPE_H_
|
||||
#define _STX_EXECPIPE_H_
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
/// STX - Some Template Extensions namespace
|
||||
namespace stx {
|
||||
|
||||
/**
|
||||
* Abstract class used as an input stream source for an ExecPipe.
|
||||
*
|
||||
* Derived classes can be used in an ExecPipe to generate an input stream
|
||||
* source. Data generated by this class is written to the first stage of the
|
||||
* pipe.
|
||||
*
|
||||
* When data is needed by the pipe the function poll() is called. This pure
|
||||
* virtual function must generate data and push it into a buffer using the
|
||||
* write() function. The input stream is terminated when poll() returns false.
|
||||
*/
|
||||
class PipeSource
|
||||
{
|
||||
private:
|
||||
/// pointer to associated pipe. filled by ExecPipe::add_input_source()
|
||||
class ExecPipeImpl* m_impl;
|
||||
|
||||
/// association to the pipe implementation for write access to m_impl.
|
||||
friend class ExecPipeImpl;
|
||||
|
||||
public:
|
||||
/// Constructor which clears m_impl.
|
||||
PipeSource();
|
||||
|
||||
/// Poll the input source for new data. The input stream is closed when
|
||||
/// this function returns false, otherwise it will be polled again.
|
||||
virtual bool poll() = 0;
|
||||
|
||||
/// Write input data to the first stage via a buffer.
|
||||
void write(const void* data, unsigned int datalen);
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract class used as an output stream source for an ExecPipe.
|
||||
*
|
||||
* Derived classes can be attached to the end of an execution pipe. It will
|
||||
* receive all data outputted by the final pipe stage.
|
||||
*
|
||||
* Data read from the final or preceding stage is passed to the class via
|
||||
* process(). When the final stage closes the pipe, the function eof() is
|
||||
* called.
|
||||
*/
|
||||
class PipeSink
|
||||
{
|
||||
public:
|
||||
/// Pure virtual function which receives the output stream as read from the
|
||||
/// final or preceding pipe stage.
|
||||
virtual void process(const void* data, unsigned int datalen) = 0;
|
||||
|
||||
/// Pure virtual function called when the final or preceding pipe stage
|
||||
/// finishes.
|
||||
virtual void eof() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract class used as an intermediate pipe stage between executed
|
||||
* processes.
|
||||
*
|
||||
* Derived classes can be inserted into an execution pipe between two
|
||||
* externally executed processes. It will receive all data from the preceding
|
||||
* pipe stage and after processing it may forward output to the next pipe
|
||||
* stage.
|
||||
*
|
||||
* The class is derived from PipeSink and receives data from the preceding
|
||||
* stage via the inherited functions process() and also the eof()
|
||||
* signal. Usually process() will perform some action on the data and then
|
||||
* forward the resulting data block to the next pipe stage via write().
|
||||
*/
|
||||
class PipeFunction : public PipeSink
|
||||
{
|
||||
private:
|
||||
/// pointer to associated pipe filled by ExecPipe::add_function()
|
||||
class ExecPipeImpl* m_impl;
|
||||
|
||||
/// pipe stage identifier
|
||||
unsigned int m_stageid;
|
||||
|
||||
/// association to the pipe implementation for write access to m_impl.
|
||||
friend class ExecPipeImpl;
|
||||
|
||||
public:
|
||||
/// Constructor which clears m_impl and m_stageid.
|
||||
PipeFunction();
|
||||
|
||||
/// Write input data to the next pipe stage via a buffer.
|
||||
void write(const void* data, unsigned int datalen);
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Main library interface (reference counted pointer)
|
||||
*
|
||||
* The ExecPipe class is the main interface to the library. It is a reference
|
||||
* counted pointer implementation, so you can easily copy and pass around
|
||||
* without duplicating the inside object. See the \ref index "main page" for
|
||||
* detailed information and examples.
|
||||
*/
|
||||
class ExecPipe
|
||||
{
|
||||
protected:
|
||||
/// reference-counted pointer implementation
|
||||
class ExecPipeImpl* m_impl;
|
||||
|
||||
public:
|
||||
/// Construct a new uninitialize execution pipe.
|
||||
ExecPipe();
|
||||
|
||||
/// Release reference to execution pipe.
|
||||
~ExecPipe();
|
||||
|
||||
/// Copy-constructor creates a new reference to the _same_ pipe.
|
||||
ExecPipe(const ExecPipe& ep);
|
||||
|
||||
/// Assignment operator creates a new reference to the right pipe.
|
||||
ExecPipe& operator=(const ExecPipe& ep);
|
||||
|
||||
// *** Debugging Output ***
|
||||
|
||||
/// Enumeration for ascending debug levels.
|
||||
enum DebugLevel
|
||||
{
|
||||
DL_ERROR=0, ///< error reporting is always active. shows failed syscalls.
|
||||
DL_INFO=1, ///< info reports at important points during pipe run.
|
||||
DL_DEBUG=2, ///< debug shows information about select() calls.
|
||||
DL_TRACE=3 ///< trace lists lots of info about read() and write() calls.
|
||||
};
|
||||
|
||||
/// Change the current debug level. The default is DL_ERROR.
|
||||
void set_debug_level(enum DebugLevel dl);
|
||||
|
||||
/// Change output function for debug messages. If set to NULL (the default)
|
||||
/// the debug lines are printed to stdout.
|
||||
void set_debug_output(void (*output)(const char *line));
|
||||
|
||||
// *** Input Selectors ***
|
||||
|
||||
///@{ \name Input Selectors
|
||||
|
||||
/**
|
||||
* Assign an already opened file descriptor as input stream for the first
|
||||
* exec stage.
|
||||
*/
|
||||
void set_input_fd(int fd);
|
||||
|
||||
/**
|
||||
* Assign a file as input stream source. This file will be opened read-only
|
||||
* and read by the first exec stage.
|
||||
*/
|
||||
void set_input_file(const char* path);
|
||||
|
||||
/**
|
||||
* Assign a std::string as input stream source. The contents of the string
|
||||
* will be written to the first exec stage. The string object is not copied
|
||||
* and must still exist when run() is called.
|
||||
*/
|
||||
void set_input_string(const std::string* input);
|
||||
|
||||
/**
|
||||
* Assign a PipeSource as input stream source. The object will be queried
|
||||
* via the read() function for data which is then written to the first exec
|
||||
* stage.
|
||||
*/
|
||||
void set_input_source(PipeSource* source);
|
||||
|
||||
///@}
|
||||
|
||||
// *** Output Selectors ***
|
||||
|
||||
///@{ \name Output Selectors
|
||||
|
||||
/**
|
||||
* Assign an already opened file descriptor as output stream for the last
|
||||
* exec stage.
|
||||
*/
|
||||
void set_output_fd(int fd);
|
||||
|
||||
/**
|
||||
* Assign a file as output stream destination. This file will be created or
|
||||
* truncated write-only and written by the last exec stage.
|
||||
*/
|
||||
void set_output_file(const char* path, int mode = 0666);
|
||||
|
||||
/**
|
||||
* Assign a std::string as output stream destination. The output of the
|
||||
* last exec stage will be stored as the contents of the string. The string
|
||||
* object is not copied and must still exist when run() is called.
|
||||
*/
|
||||
void set_output_string(std::string* output);
|
||||
|
||||
/**
|
||||
* Assign a PipeSink as output stream destination. The object will receive
|
||||
* data via the process() function and is informed via eof()
|
||||
*/
|
||||
void set_output_sink(PipeSink* sink);
|
||||
|
||||
///@}
|
||||
|
||||
// *** Pipe Stages ***
|
||||
|
||||
///@{ \name Add Pipe Stages
|
||||
|
||||
/**
|
||||
* Return the number of pipe stages added.
|
||||
*/
|
||||
unsigned int size() const;
|
||||
|
||||
/**
|
||||
* Add an exec() stage to the pipe with given arguments. Note that argv[0]
|
||||
* is set to prog.
|
||||
*/
|
||||
void add_exec(const char* prog);
|
||||
|
||||
/**
|
||||
* Add an exec() stage to the pipe with given arguments. Note that argv[0]
|
||||
* is set to prog.
|
||||
*/
|
||||
void add_exec(const char* prog, const char* arg1);
|
||||
|
||||
/**
|
||||
* Add an exec() stage to the pipe with given arguments. Note that argv[0]
|
||||
* is set to prog.
|
||||
*/
|
||||
void add_exec(const char* prog, const char* arg1, const char* arg2);
|
||||
|
||||
/**
|
||||
* Add an exec() stage to the pipe with given arguments. Note that argv[0]
|
||||
* is set to prog.
|
||||
*/
|
||||
void add_exec(const char* prog, const char* arg1, const char* arg2, const char* arg3);
|
||||
|
||||
/**
|
||||
* Add an exec() stage to the pipe with given arguments. The vector of
|
||||
* arguments is not copied, so it must still exist when run() is
|
||||
* called. Note that the program called is args[0].
|
||||
*/
|
||||
void add_exec(const std::vector<std::string>* args);
|
||||
|
||||
|
||||
/**
|
||||
* Add an execp() stage to the pipe with given arguments. The PATH variable
|
||||
* is search for programs not containing a slash / character. Note that
|
||||
* argv[0] is set to prog.
|
||||
*/
|
||||
void add_execp(const char* prog);
|
||||
|
||||
/**
|
||||
* Add an execp() stage to the pipe with given arguments. The PATH variable
|
||||
* is search for programs not containing a slash / character. Note that
|
||||
* argv[0] is set to prog.
|
||||
*/
|
||||
void add_execp(const char* prog, const char* arg1);
|
||||
|
||||
/**
|
||||
* Add an execp() stage to the pipe with given arguments. The PATH variable
|
||||
* is search for programs not containing a slash / character. Note that
|
||||
* argv[0] is set to prog.
|
||||
*/
|
||||
void add_execp(const char* prog, const char* arg1, const char* arg2);
|
||||
|
||||
/**
|
||||
* Add an execp() stage to the pipe with given arguments. The PATH variable
|
||||
* is search for programs not containing a slash / character. Note that
|
||||
* argv[0] is set to prog.
|
||||
*/
|
||||
void add_execp(const char* prog, const char* arg1, const char* arg2, const char* arg3);
|
||||
|
||||
/**
|
||||
* Add an execp() stage to the pipe with given arguments. The PATH variable
|
||||
* is search for programs not containing a slash / character. The vector of
|
||||
* arguments is not copied, so it must still exist when run() is
|
||||
* called. Note that the program called is args[0].
|
||||
*/
|
||||
void add_execp(const std::vector<std::string>* args);
|
||||
|
||||
/**
|
||||
* Add an exece() stage to the pipe with the given arguments and
|
||||
* environments. This is the most flexible exec() call. The vector of
|
||||
* arguments and environment variables is not copied, so it must still
|
||||
* exist when run() is called. The args[0] is _not_ override with path, so
|
||||
* you can fake program name calls.
|
||||
*/
|
||||
void add_exece(const char* path,
|
||||
const std::vector<std::string>* args,
|
||||
const std::vector<std::string>* env);
|
||||
|
||||
/**
|
||||
* Add a function stage to the pipe. This function object will be called in
|
||||
* the parent process with data passing through the stage. See PipeFunction
|
||||
* for more information.
|
||||
*/
|
||||
void add_function(PipeFunction* func);
|
||||
|
||||
///@}
|
||||
|
||||
// *** Run Pipe ***
|
||||
|
||||
/**
|
||||
* Run the configured pipe sequence and wait for all children processes to
|
||||
* complete. Returns a reference to *this for chaining.
|
||||
*
|
||||
* This function call should be wrapped into a try-catch block as it will
|
||||
* throw() if a system call fails.
|
||||
*/
|
||||
ExecPipe& run();
|
||||
|
||||
// *** Inspection After Pipe Execution ***
|
||||
|
||||
///@{ \name Inspect Return Codes
|
||||
|
||||
/**
|
||||
* Get the return status of exec() stage's program run after pipe execution
|
||||
* as indicated by wait().
|
||||
*/
|
||||
int get_return_status(unsigned int stageid) const;
|
||||
|
||||
/**
|
||||
* Get the return code of exec() stage's program run after pipe execution,
|
||||
* or -1 if the program terminated abnormally.
|
||||
*/
|
||||
int get_return_code(unsigned int stageid) const;
|
||||
|
||||
/**
|
||||
* Get the signal of the abnormally terminated exec() stage's program run
|
||||
* after pipe execution, or -1 if the program terminated normally.
|
||||
*/
|
||||
int get_return_signal(unsigned int stageid) const;
|
||||
|
||||
/**
|
||||
* Return true if the return code of all exec() stages were zero.
|
||||
*/
|
||||
bool all_return_codes_zero() const;
|
||||
|
||||
///@}
|
||||
};
|
||||
|
||||
} // namespace stx
|
||||
|
||||
#endif // _STX_EXECPIPE_H_
|
||||
78
xmake.lua
Normal file
78
xmake.lua
Normal file
@@ -0,0 +1,78 @@
|
||||
add_rules("mode.debug", "mode.release")
|
||||
|
||||
set_languages("c++11")
|
||||
|
||||
target("Songdle")
|
||||
set_kind("binary")
|
||||
add_files("src/*.cpp")
|
||||
set_rundir(".")
|
||||
|
||||
--
|
||||
-- If you want to known more usage about xmake, please see https://xmake.io
|
||||
--
|
||||
-- ## FAQ
|
||||
--
|
||||
-- You can enter the project directory firstly before building project.
|
||||
--
|
||||
-- $ cd projectdir
|
||||
--
|
||||
-- 1. How to build project?
|
||||
--
|
||||
-- $ xmake
|
||||
--
|
||||
-- 2. How to configure project?
|
||||
--
|
||||
-- $ xmake f -p [macosx|linux|iphoneos ..] -a [x86_64|i386|arm64 ..] -m [debug|release]
|
||||
--
|
||||
-- 3. Where is the build output directory?
|
||||
--
|
||||
-- The default output directory is `./build` and you can configure the output directory.
|
||||
--
|
||||
-- $ xmake f -o outputdir
|
||||
-- $ xmake
|
||||
--
|
||||
-- 4. How to run and debug target after building project?
|
||||
--
|
||||
-- $ xmake run [targetname]
|
||||
-- $ xmake run -d [targetname]
|
||||
--
|
||||
-- 5. How to install target to the system directory or other output directory?
|
||||
--
|
||||
-- $ xmake install
|
||||
-- $ xmake install -o installdir
|
||||
--
|
||||
-- 6. Add some frequently-used compilation flags in xmake.lua
|
||||
--
|
||||
-- @code
|
||||
-- -- add debug and release modes
|
||||
-- add_rules("mode.debug", "mode.release")
|
||||
--
|
||||
-- -- add macro definition
|
||||
-- add_defines("NDEBUG", "_GNU_SOURCE=1")
|
||||
--
|
||||
-- -- set warning all as error
|
||||
-- set_warnings("all", "error")
|
||||
--
|
||||
-- -- set language: c99, c++11
|
||||
-- set_languages("c99", "c++11")
|
||||
--
|
||||
-- -- set optimization: none, faster, fastest, smallest
|
||||
-- set_optimize("fastest")
|
||||
--
|
||||
-- -- add include search directories
|
||||
-- add_includedirs("/usr/include", "/usr/local/include")
|
||||
--
|
||||
-- -- add link libraries and search directories
|
||||
-- add_links("tbox")
|
||||
-- add_linkdirs("/usr/local/lib", "/usr/lib")
|
||||
--
|
||||
-- -- add system link libraries
|
||||
-- add_syslinks("z", "pthread")
|
||||
--
|
||||
-- -- add compilation and link flags
|
||||
-- add_cxflags("-stdnolib", "-fno-strict-aliasing")
|
||||
-- add_ldflags("-L/usr/local/lib", "-lpthread", {force = true})
|
||||
--
|
||||
-- @endcode
|
||||
--
|
||||
|
||||
Reference in New Issue
Block a user