summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Houghton2017-06-29 14:08:42 -0400
committerJames Houghton2017-06-29 14:08:42 -0400
commit910317f82949d53cdf44717c202f7957bd8edf9e (patch)
tree034757c2472a3217f51653159dbcc374d2f2e477
parent21cb16514487978fa6a684810a2933ae4bebdd92 (diff)
downloadaur-ttyvideo.tar.gz
Follow twa022's instructions
-rw-r--r--.SRCINFO12
-rw-r--r--.gitignore10
-rw-r--r--CMakeLists.txt21
-rw-r--r--PKGBUILD26
-rw-r--r--README.md21
-rw-r--r--handle.c174
-rw-r--r--handle.h30
-rw-r--r--ttyvideo.cpp306
8 files changed, 19 insertions, 581 deletions
diff --git a/.SRCINFO b/.SRCINFO
index f2da0e7978a4..10b561bbf1e0 100644
--- a/.SRCINFO
+++ b/.SRCINFO
@@ -1,16 +1,16 @@
pkgbase = ttyvideo
- pkgdesc = ttyvideo displays videos in the terminal.
+ pkgdesc = Play video in the terminal
pkgver = 0.0.1
- pkgrel = 1
+ pkgrel = 2
url = https://github.com/jamesthoughton/ttyvideo
- arch = any
+ arch = i686
+ arch = x86_64
license = MIT
makedepends = cmake
depends = opencv
- depends = gstreamer
depends = gst-plugins-base
- source = https://github.com/jamesthoughton/ttyvideo/archive/0.0.1.tar.gz
- md5sums = 862c8cf756ad896f82654565ffc7f5ad
+ source = ttyvideo-0.0.1.tar.gz::https://github.com/jamesthoughton/ttyvideo/archive/0.0.1.tar.gz
+ sha256sums = ecceca05dcfd94cadd0f17f58e3e98a93f5ee7ffe70a72e6935edf5e4a73fcc2
pkgname = ttyvideo
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 0c7f348b2bfc..000000000000
--- a/.gitignore
+++ /dev/null
@@ -1,10 +0,0 @@
-opencv/
-CMake*
-!CMakeLists.txt
-cmake_install.cmake
-*.a
-*.o
-*.so
-ttyvideo
-Makefile
-install_manifest.txt
diff --git a/CMakeLists.txt b/CMakeLists.txt
deleted file mode 100644
index 2cc034700bdd..000000000000
--- a/CMakeLists.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-cmake_minimum_required(VERSION 2.8)
-project(ttyvideo)
-find_package(OpenCV REQUIRED)
-
-if(MSVC)
- # Visual Studio -- /W4
- if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
- string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
- else()
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
- endif()
-elseif(CMAKE_COMPILER_IS_GNUXX OR CMAKE_COMPILER_IS_GNUCC)
- # GCC -- -Wall -pedantic
- set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic")
-endif()
-
-add_library(handle STATIC handle.c)
-add_executable(ttyvideo ttyvideo.cpp)
-target_link_libraries(ttyvideo ${OpenCV_LIBS} -lm handle)
-
-install(TARGETS ttyvideo DESTINATION bin)
diff --git a/PKGBUILD b/PKGBUILD
index 251ddf49ef04..cf6bf25cd921 100644
--- a/PKGBUILD
+++ b/PKGBUILD
@@ -1,22 +1,22 @@
pkgname=ttyvideo
-pkgver='0.0.1'
-pkgrel='1'
-pkgdesc="ttyvideo displays videos in the terminal."
-arch=('any')
+pkgver=0.0.1
+pkgrel=2
+pkgdesc="Play video in the terminal"
+arch=('i686' 'x86_64')
license=('MIT')
-depends=(opencv gstreamer gst-plugins-base)
-makedepends=(cmake)
-source=("https://github.com/jamesthoughton/ttyvideo/archive/0.0.1.tar.gz")
+depends=('opencv' 'gst-plugins-base')
+makedepends=('cmake')
+source=("${pkgname}-${pkgver}.tar.gz::https://github.com/jamesthoughton/${pkgname}/archive/${pkgver}.tar.gz")
url='https://github.com/jamesthoughton/ttyvideo'
-md5sums=('862c8cf756ad896f82654565ffc7f5ad')
+sha256sums=('ecceca05dcfd94cadd0f17f58e3e98a93f5ee7ffe70a72e6935edf5e4a73fcc2')
build() {
- cd $srcdir/$pkgname-$pkgver
- cmake .
- make
+ cd "${pkgname}-${pkgver}"
+ cmake . -DCMAKE_INSTALL_PREFIX=/usr
+ make
}
package() {
- cd $srcdir/$pkgname-$pkgver
- install -Dm 755 ttyvideo $pkgdir/usr/bin/ttyvideo
+ cd "${pkgname}-${pkgver}"
+ make DESTDIR="${pkgdir}" install
}
diff --git a/README.md b/README.md
deleted file mode 100644
index 671d6f9be322..000000000000
--- a/README.md
+++ /dev/null
@@ -1,21 +0,0 @@
-# ttyvideo
-Pushing the limits of resolution and color depth... backwards!
-ttyvideo is a video player that runs in a 256-color terminal.
-## Dependencies
-ttyvideo requires OpenCV (2 or 3) compiled with video codecs. If your package manager doesn't carry a version of OpenCV like this, you're going to need to download and compile its [source code](https://github.com/opencv/opencv "OpenCV source") before you can use ttyvideo.
-ttyvideo also uses CMake>=2.8 to generate files used in the installation process.
-## Installation
-You can compile ttyvideo with CMake and Make.
-```shell
-cmake .
-make
-```
-After compiling, it can be installed by performing
-```shell
-sudo make install
-```
-
-## How it works
-ttyvideo works with most visual media types: videos, images, GIFs, etc. This is due to the usage of OpenCV to read media.
-Right now, ttyvideo doesn't do anything special when rendering videos.
-ttyvideo will scale any video to fit the aspect ratio of the terminal it's running in. ttyvideo also does not perform any smoothing operations; each character slot in the terminal corresponds to exactly one pixel in the source video, not a combination of them. Feel free to add smoothing ttyvideo!
diff --git a/handle.c b/handle.c
deleted file mode 100644
index 1d18b8c2fc82..000000000000
--- a/handle.c
+++ /dev/null
@@ -1,174 +0,0 @@
-#include "handle.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <signal.h>
-
-int error(char* message) {
-
- fprintf(stderr, "%s: %s\n", "ttyvideo", message);
-
- return 1;
-
-}
-
-static int numOptionsSpecified = 0;
-static int numUniqueOptionsSpecified = 0;
-static char** argumentCallMap = NULL;
-static char** argumentMemStore = NULL;
-static int* argumentNumStore = NULL;
-static char** helpMessages = NULL;
-static char* defaultArg = NULL;
-static char* defaultArgHelp = NULL;
-
-#define MAX_ARG_SIZE 200
-
-char* setDefaultArgument(char* helpText) {
-
- defaultArg = (char*)malloc(sizeof(char) * MAX_ARG_SIZE);
- defaultArgHelp = (char*)malloc(sizeof(char) * strlen(helpText));
- strcpy(defaultArgHelp, helpText);
-
- defaultArg[0] = '\0';
-
- return defaultArg;
-
-}
-
-#define MAX_ACCESS_MAP_SIZE 100
-#define MAX_HELP_MESSAGE_ARRAY_SIZE 100
-
-char* addArgument(char* helpText, int numArguments, char* firstCall, char* secondCall) {
-
- if(firstCall == NULL) {
- fprintf(stderr, "No option specified for parameter\n");
- return NULL;
- }
- if(firstCall[0] != '-') {
- fprintf(stderr, "Option '%s' does not start with a '-'\n", firstCall);
- return NULL;
- }
- if(secondCall != NULL && secondCall[0] != '-') {
- fprintf(stderr, "Option '%s' does not start with a '-'\n", secondCall);
- }
-
- if(argumentCallMap == NULL) {
- argumentCallMap = (char**)malloc(sizeof(char*) * MAX_ACCESS_MAP_SIZE);
- }
- if(argumentMemStore == NULL) {
- argumentMemStore = (char**)malloc(sizeof(char*) * MAX_ACCESS_MAP_SIZE);
- }
- if(argumentNumStore == NULL) {
- argumentNumStore = (int*)malloc(sizeof(int*) * MAX_ACCESS_MAP_SIZE);
- }
- if(helpMessages == NULL) {
- helpMessages = (char**)malloc(sizeof(char*) * MAX_HELP_MESSAGE_ARRAY_SIZE);
- }
-
- // TODO: Add ability to allocate lots of these
- char* argumentMemLocation = (char*)malloc(sizeof(char) * MAX_ARG_SIZE);
- if(argumentMemLocation == NULL) {
- fprintf(stderr, "Couldn't allocate memory to store argument to pass to %s", firstCall);
- return NULL;
- }
- argumentMemLocation[0] = '\0';
-
- int argumentAccessLocation = numOptionsSpecified++;
- argumentCallMap[argumentAccessLocation] = (char*)malloc(sizeof(char) * strlen(firstCall));
- strcpy(argumentCallMap[argumentAccessLocation], firstCall);
- argumentMemStore[argumentAccessLocation] = argumentMemLocation;
- argumentNumStore[argumentAccessLocation] = numArguments;
-
-
- if(secondCall == NULL) {
-
- helpMessages[numUniqueOptionsSpecified] = (char*)malloc(sizeof(char) * (strlen(helpText) + strlen(firstCall) + 4));
-
- strcpy(helpMessages[numUniqueOptionsSpecified], firstCall);
- strcat(helpMessages[numUniqueOptionsSpecified], ":\t");
- strcat(helpMessages[numUniqueOptionsSpecified], helpText);
-
- numUniqueOptionsSpecified++;
-
- return argumentMemLocation;
- }
-
- helpMessages[numUniqueOptionsSpecified] = (char*)malloc(sizeof(char) * (strlen(helpText) + strlen(firstCall) + 2 + 4 + strlen(secondCall)));
-
- strcpy(helpMessages[numUniqueOptionsSpecified], firstCall);
- strcat(helpMessages[numUniqueOptionsSpecified], ", ");
- strcat(helpMessages[numUniqueOptionsSpecified], secondCall);
- strcat(helpMessages[numUniqueOptionsSpecified], ":\t");
- strcat(helpMessages[numUniqueOptionsSpecified], helpText);
-
- numUniqueOptionsSpecified++;
-
- argumentAccessLocation = numOptionsSpecified++;
- argumentCallMap[argumentAccessLocation] = (char*)malloc(sizeof(char) * strlen(secondCall));
- strcpy(argumentCallMap[argumentAccessLocation], secondCall);
- argumentMemStore[argumentAccessLocation] = argumentMemLocation;
- argumentNumStore[argumentAccessLocation] = numArguments;
-
- return argumentMemLocation;
-}
-
-void printUsage() {
-
- if(helpMessages != NULL) {
- register int i;
- for(i = 0; i < numUniqueOptionsSpecified; ++i) {
- printf("%s\n", helpMessages[i]);
- }
- } else {
- printf("No options to display\n");
- }
-
-}
-
-int handle(int argc, char** argv) {
-
- register int i, j;
- int numArguments;
- for(i = 1; i < argc; ++i) {
- for(j = 0; j < numOptionsSpecified; ++j) {
- if(argv[i][0] != '-') {
- if(defaultArg == NULL) {
- fprintf(stderr, "Argument '%s' was passed without an option, and no default argument has been set\n", argv[0]);
- return 1;
- }
- if(defaultArg[0] != '\0') {
- fprintf(stderr, "Unrecognized option '%s'\n", argv[i]);
- return 1;
- }
- strcpy(defaultArg, argv[i]);
- break;
- }
- if(strcmp(argv[i], argumentCallMap[j]))
- continue;
- numArguments = argumentNumStore[j];
- if(numArguments) {
- if(i < argc - 1 && argv[i+1][0] != '-') {
- strcpy(argumentMemStore[j], argv[++i]);
- } else {
- fprintf(stderr, "Option '%s' requires an argument\n", argv[i]);
- return 1;
- }
- }
- else
- strcpy(argumentMemStore[j], "1"); // The option is present
- break;
- }
- if(j == numOptionsSpecified) {
- fprintf(stderr, "Unrecognized option '%s'\n", argv[i]);
- return 1;
- }
- }
-
- return 0;
-
-}
-
-void sig_handler(int signo) {
- if(signo == SIGINT)
- terminate = 1;
-}
diff --git a/handle.h b/handle.h
deleted file mode 100644
index 5a8f6806628e..000000000000
--- a/handle.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef HANDLE_H
-#define HANDLE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-char* filename;
-
-char* setDefaultArgument(char* helpText);
-
-char* addArgument(char* helpText, int numArguments, char* firstCall, char* secondCall);
-
-void printUsage();
-
-int error(char* message);
-int handle(int argc, char** argv);
-
-int terminate;
-
-#define TAKES_NO_ARGUMENTS 0
-#define TAKES_ONE_ARGUMENT 1
-
-void sig_handler(int signo);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // HANDLE_H
diff --git a/ttyvideo.cpp b/ttyvideo.cpp
deleted file mode 100644
index 361eaf20373b..000000000000
--- a/ttyvideo.cpp
+++ /dev/null
@@ -1,306 +0,0 @@
-// #include <opencv2/core/core_c.h>
-// #include <opencv2/videoio/videoio_c.h>
-// #include <opencv2/videoio/videoio.hpp>
-#include <opencv2/core.hpp>
-#include <opencv2/video.hpp>
-#include <opencv2/highgui.hpp>
-#include <opencv2/opencv.hpp>
-#include <math.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "handle.h"
-#include <sys/ioctl.h>
-#include <time.h>
-#include <unistd.h>
-#include <signal.h>
-
-#ifdef __MACH__
-#include <mach/clock.h>
-#include <mach/mach.h>
-#endif
-
-#define NANO_CONV_FACTOR 1000000000
-
-#define COLOR_TEXT_FORMAT "\x1B[48;05;%um\x1B[38;05;%um%c"
-#define COLOR_FORMAT "\x1B[48;05;%um "
-#define COLOR_RESET "\x1B[0m"
-
-int waitFrame(uint64_t, uint64_t);
-unsigned char generateANSIColor(unsigned char, unsigned char, unsigned char);
-void getTTYDims();
-int play(char*, char*, char*, int);
-void getSystemTime(struct timespec*);
-
-int tty_width;
-int tty_height;
-int tty_width_custom = 0;
-int tty_height_custom = 0;
-
-int no_interrupts = 0;
-
-#define C (char*)
-
-int main(int argc, char** argv) {
-
- char* filename = setDefaultArgument(C"infile");
- char* width_option = addArgument(C"Output width", TAKES_ONE_ARGUMENT, C"-w", C"--width");
- char* height_option = addArgument(C"Output height", TAKES_ONE_ARGUMENT, C"-h", C"--height");
- char* sleep_option = addArgument(C"Add a pause between loops or after plays (seconds)", TAKES_ONE_ARGUMENT, C"-s", C"--sleep");
- char* noexit_option = addArgument(C"Prevent the program for exiting", TAKES_NO_ARGUMENTS, C"--no-exit", NULL);
- char* loop_option = addArgument(C"Loop videos", TAKES_NO_ARGUMENTS, C"-l", C"--loop");
- char* help_option = addArgument(C"Print usage", TAKES_NO_ARGUMENTS, C"--help", NULL);
- char* nointer_option = addArgument(C"No interrupts", TAKES_NO_ARGUMENTS, C"--no-interrupts", NULL);
- char* fps_option = addArgument(C"FPS", TAKES_ONE_ARGUMENT, C"--fps", NULL);
- char* string_option = addArgument(C"String to place in the foreground", TAKES_ONE_ARGUMENT, C"--string", NULL);
- char* info_option = addArgument(C"Print terminal dimensions", TAKES_NO_ARGUMENTS, C"-i", C"--info");
-
- int argError;
- argError = handle(argc, argv);
- if(argError) {
- error((char*)"Run ttyvideo --help for more information");
- return argError;
- }
-
- if(help_option[0] != '\0') {
- printUsage();
- return 0;
- }
-
- if(info_option[0] != '\0') {
- getTTYDims();
- printf("Height: %d\nWidth: %d\n",
- tty_height, tty_width);
- return 0;
- }
-
- if(filename[0] == '\0')
- return error((char*)"No input file specified");
-
- getTTYDims(); // get initial dims
-
- tty_height_custom = atoi(height_option);
- tty_width_custom = atoi(width_option);
-
- if(tty_height == 0 && tty_width == 0) {
- if(tty_height_custom == 0 || tty_width_custom == 0) {
- error((char*)"Could not detect terminal dimensions and specified dimensions are incomplete");
- return 1;
- }
- } else {
- if(tty_height_custom > tty_height || tty_width_custom > tty_width) {
- error((char*)"The specified dimensions are too large, but we will play the video anyway");
- }
- }
-
- getTTYDims(); // get real dims -- including user specification
-
- int sleep_time = sleep_option[0] == '\0' ? 0 : atoi(sleep_option);
-
- int noexit = noexit_option[0] == '\0' ? 0 : 1;
-
- int loop = loop_option[0] == '\0' ? 0 : 1;
-
- setvbuf(stdout, NULL, _IOFBF, 0);
-
- signal(SIGINT, sig_handler);
-
- no_interrupts = nointer_option[0] == '\0' ? 0 : 1;
-
- register int frameNum = 0;
- do {
- frameNum = play(filename, string_option, fps_option, frameNum);
-
- if(frameNum < 0)
- return 1;
-
- if(terminate && !no_interrupts) {
- printf("\n");
- fflush(stdout);
- return 0;
- }
-
- if(sleep_time)
- sleep(sleep_time);
-
- } while(loop && frameNum > 1);
-
- if((loop && frameNum == 1) || noexit) {
- terminate = 0; // Terminate to 0 so we can work with it
- while(true) {
- sleep(1);
- // When SIG_INT is sent to a frozen frame,
- // re-render the frame
- if(terminate) {
- if(!no_interrupts) return 0;
- frameNum = play(filename, string_option, fps_option, frameNum);
- terminate = 0;
- }
- }
- }
-
- printf("\n");
- fflush(stdout);
- return 0;
-
-}
-
-int play(char* filename, char* string, char* fps_option, int subsequentPlay) {
- cv::VideoCapture cap(filename);
- if(!cap.isOpened()) return -1 * error((char*)"Can't read input");
-
- double fps = fps_option[0] == '\0' ? cap.get(CV_CAP_PROP_FPS) : atof(fps_option);
-
- struct timespec start, end;
-
- uint64_t delta_ns;
- uint64_t delayNecessary = fps == 0 || isnan(fps) ? 0 : NANO_CONV_FACTOR/fps;
-
- register int frameNum = 0;
-
- register int width, height, nchannels, step, offset;
- register int i, j;
- register unsigned char r_ch, b_ch, g_ch;
- cv::Mat frame;
- int ansiColor, ansiTextColor;
- unsigned char* data;
-
- int stringLength = strlen(string);
-
- int stopAfterFrame = 0;
-
- for(;;) {
-
- getSystemTime(&start);
-
- if(!frame.empty() || subsequentPlay) {
-
- cap >> frame;
-
- if(frame.empty()) break;
-
- for(i = 0; i < tty_height - 1; ++i)
- printf("\x1B[F");
-
- } else {
-
- cap >> frame;
-
- if(frame.empty()) break;
-
- }
-
- if(frame.depth() != CV_8U) {
- return -1 * error((char*)"Frame has incorrect depth");
- }
-
- width = frame.cols;
- height = frame.rows;
- nchannels = frame.channels();
- step = width * nchannels;
-
- getTTYDims();
-
- register int stringIter = 0;
-
- for(i = 0; i < tty_height; ++i) {
- data = (unsigned char*)(frame.data + ((int)((float)i*height/tty_height)*step));
- for(j = 0; j < tty_width; ++j) {
- offset = (int)((float)j*width/tty_width) * nchannels;
- b_ch = data[offset];
- g_ch = data[offset+1];
- r_ch = data[offset+2];
-
- ansiColor = generateANSIColor(r_ch, g_ch, b_ch);
-
- if(stringLength) {
- ansiTextColor = b_ch + g_ch + r_ch > 0x17F ? generateANSIColor(r_ch - 50, g_ch - 50, b_ch - 50) :
- generateANSIColor(r_ch + 50, g_ch + 50, b_ch + 50);
-
- printf(COLOR_TEXT_FORMAT, ansiColor, ansiTextColor, string[stringIter++%stringLength]);
- } else {
- printf(COLOR_FORMAT, ansiColor);
- }
- }
- printf(COLOR_RESET);
- if(i < tty_height - 1) {
- printf("\n");
- } else {
- printf("\x1B[m");
- fflush(stdout);
- }
- }
-
- if(stopAfterFrame) {
- break;
- }
-
- if(terminate && !no_interrupts) {
- stopAfterFrame = 1;
- }
-
- getSystemTime(&end);
-
- delta_ns = (end.tv_sec - start.tv_sec) * NANO_CONV_FACTOR + (end.tv_nsec - start.tv_nsec);
-
- waitFrame(delayNecessary, delta_ns);
-
- frameNum++;
-
- }
-
- return frameNum;
-
-}
-
-int waitFrame(uint64_t delayNecessary, uint64_t delta_ns) {
-
- struct timespec ts;
- long totalNanoSec;
-
- totalNanoSec = (delayNecessary - delta_ns);
-
- if(totalNanoSec < 0) return 1;
-
- ts.tv_sec = totalNanoSec/NANO_CONV_FACTOR;
- ts.tv_nsec = totalNanoSec%NANO_CONV_FACTOR;
- nanosleep(&ts, NULL);
-
- return 0;
-
-}
-
-unsigned char generateANSIColor(unsigned char r, unsigned char g, unsigned char b) {
-
- return 16 + (36 * lround(r*5.0/256)) + (6 * lround(g*5.0/256)) + lround(b*5.0/256);
-
-}
-
-void getTTYDims() {
-
- struct winsize w;
- ioctl(STDOUT_FILENO, TIOCGWINSZ, &w);
- tty_width = tty_width_custom > 0 ? tty_width_custom : w.ws_col;
- tty_height = tty_height_custom > 0 ? tty_height_custom : w.ws_row;
-
-}
-
-void getSystemTime(struct timespec* tv) {
-
- #ifdef __MACH__
-
- clock_serv_t cclock;
- mach_timespec_t mts;
- host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
- clock_get_time(cclock, &mts);
- mach_port_deallocate(mach_task_self(), cclock);
-
- tv->tv_sec = mts.tv_sec;
- tv->tv_nsec = mts.tv_nsec;
-
- #else
-
- clock_gettime(CLOCK_REALTIME, tv);
-
- #endif
-
-}