-
-
Save FMudanyali/6ca2a4c6cb1b903885044dbfa513ce53 to your computer and use it in GitHub Desktop.
#include <stdio.h> | |
#include <sys/ioctl.h> | |
#include <stdlib.h> | |
#include <time.h> | |
#include <libavformat/avformat.h> | |
#include <unistd.h> | |
void draw_bmp(uint32_t frame_count, char *filename, uint8_t framerate){ | |
FILE *bmp_handle; | |
FILE *buffer_handle; | |
buffer_handle = fopen("buffer.txt","w"); | |
struct winsize w; | |
ioctl(0, TIOCGWINSZ, &w); | |
uint16_t lines = w.ws_row; | |
uint16_t columns = w.ws_col; | |
uint8_t pixel; | |
uint16_t batch = 1; | |
uint32_t filejump = 0; | |
uint32_t size, offset, static_offset, width, height; | |
char buf[0x100]; | |
// Repeat for all frames. | |
for(int i = 1; i <= frame_count; ++i){ | |
if(batch==1){ | |
snprintf(buf, sizeof(buf), "ffmpeg -i \"%s\" -vf \"select=between(n\\,%d\\,%d)\" -vsync 0 -pix_fmt bgr8 -y temp-termplayer/bitmap%%01d.bmp >/dev/null 2>/dev/null", filename, filejump, filejump+1999); | |
system(buf); | |
} | |
snprintf(buf, sizeof(buf), "temp-termplayer/bitmap%d.bmp", batch); | |
bmp_handle = fopen(buf,"r"); | |
// size | |
fseek(bmp_handle,0x02, SEEK_SET); | |
fread(&size,4,1,bmp_handle); | |
// offset | |
fseek(bmp_handle,0x0A,SEEK_SET); | |
fread(&static_offset,4,1,bmp_handle); | |
// width, height | |
fseek(bmp_handle,0x12,SEEK_SET); | |
fread(&width,4,1,bmp_handle); | |
fread(&height,4,1,bmp_handle); | |
uint16_t new_width; | |
// Respect aspect ratio. Note: not working so always true | |
if((float)(width/height) < (float)(16/9) || 1){ | |
new_width = lines*3; | |
} else { | |
new_width = columns; | |
} | |
uint16_t width_offset = (columns - new_width)/2; | |
// Read according to the terminal resolution. | |
uint16_t jump_width = width/new_width; | |
uint16_t jump_height = height/lines; | |
//printf("width %d, height %d, lines %d, columns %d, new_width %d, jump_width %d, jump_height %d\n",width,height,lines,columns,new_width,jump_width,jump_height); | |
//return; | |
// BMP stores image upside down. Set offset to last horizontal line. | |
offset = static_offset + width * height - width; | |
// Y axis. | |
for(int j = 1; j < lines+1; ++j){ | |
// X axis. | |
fseek(bmp_handle,offset,SEEK_SET); | |
for(int k = 0; k < width_offset+4; ++k){ | |
fputc(' ',buffer_handle); | |
} | |
for(int k = 1; k < new_width-7; ++k){ | |
fread(&pixel,1,1,bmp_handle); | |
if (pixel > 235) fputc('#',buffer_handle); | |
else if (pixel > 148) fputc('+',buffer_handle); | |
else if (pixel > 96) fputc(':',buffer_handle); | |
else if (pixel > 0) fputc('.',buffer_handle); | |
else fputc(' ',buffer_handle); | |
fseek(bmp_handle,jump_width,SEEK_CUR); | |
} | |
for(int k = new_width+width_offset; k < columns+3; ++k){ | |
fputc(' ',buffer_handle); | |
} | |
fputc('\n',buffer_handle); | |
// Go up one line. | |
offset = static_offset + width*height - (j*width*jump_height); | |
} | |
fclose(bmp_handle); | |
++batch; | |
if(batch == 2000){ | |
batch = 1; | |
filejump += 2000; | |
} | |
} | |
fclose(buffer_handle); | |
system("rm temp-termplayer/*.bmp >/dev/null 2>/dev/null"); | |
buffer_handle = fopen("buffer.txt","r"); | |
printf("\n"); | |
char line[columns]; | |
uint8_t line_count = 0; | |
int pid = fork(); | |
if (pid == 0){ | |
#ifdef __linux | |
system("aplay temp-termplayer/audio.wav >/dev/null 2>/dev/null"); | |
#else //macos | |
system("afplay temp-termplayer/audio.wav >/dev/null 2>/dev/null"); | |
#endif | |
return; | |
} | |
while(fgets(line, sizeof(line), buffer_handle)){ | |
printf("%s",line); | |
++line_count; | |
if (line_count == lines*2){ | |
line_count = 0; | |
usleep((33000)); | |
} | |
} | |
fclose(buffer_handle); | |
} | |
int main(int argc, char *argv[]){ | |
if (argc < 2){ | |
printf("Provide a video please.\n"); | |
return 0; | |
} | |
AVFormatContext *pFormatCtx = NULL; | |
if (avformat_open_input(&pFormatCtx, argv[1], NULL, NULL) != 0) | |
return -1; | |
if (avformat_find_stream_info(pFormatCtx, NULL) < 0) | |
return -1; | |
uint32_t duration = (uint32_t)(pFormatCtx->duration/1000000); | |
uint8_t framerate = pFormatCtx->streams[0]->r_frame_rate.num / pFormatCtx->streams[0]->r_frame_rate.den; | |
uint32_t frame_count = framerate * duration; | |
char buf[0x100]; | |
system("mkdir temp-termplayer >/dev/null 2>/dev/null"); | |
snprintf(buf, sizeof(buf), "ffmpeg -i \"%s\" -y temp-termplayer/audio.wav >/dev/null 2>/dev/null", argv[1]); | |
system(buf); | |
draw_bmp(frame_count, argv[1], framerate); | |
return 0; | |
} |
Yoo thank you too!
[felix@ArtwixLinwux ~]$ gcc bad_apple.c -o bad_apple /usr/bin/ld: /tmp/ccZy4GpA.o: in function
main':
bad_apple.c:(.text+0x71a): undefined reference to avformat_open_input' /usr/bin/ld: bad_apple.c:(.text+0x73c): undefined reference to
avformat_find_stream_info'
collect2: error: ld returned 1 exit status`
Can someone help me?
Thanks
[felix@ArtwixLinwux ~]$ gcc bad_apple.c -o bad_apple /usr/bin/ld: /tmp/ccZy4GpA.o: in function
main': bad_apple.c:(.text+0x71a): undefined reference toavformat_open_input' /usr/bin/ld: bad_apple.c:(.text+0x73c): undefined reference to
avformat_find_stream_info' collect2: error: ld returned 1 exit status`Can someone help me? Thanks
You probably forgot to install libavformat, in Artix/arch, i think it should be in ffmpeg package. Try compiling after installing that.
Woah this is Really Spot on, Thanks bud.