| 46 | |
| 47 | |
| 48 | AVEncoder::AVEncoder() { |
| 49 | std::ostringstream commandline; |
| 50 | commandline << "ffmpeg -xerror -hide_banner -y -f nut -i - "; |
| 51 | commandline << ffmpeg_options; |
| 52 | commandline << " \""; |
| 53 | char* dumpfile_ext = strrchr(dumpfile, '.'); |
| 54 | if (dumpfile_ext == NULL) dumpfile_ext = dumpfile + strnlen(dumpfile, 4096); |
| 55 | |
| 56 | commandline.write(dumpfile, static_cast<int>(dumpfile_ext - dumpfile)); |
| 57 | /* Add segment number to filename if not the first */ |
| 58 | if (segment_number > 0) { |
| 59 | commandline << "_" << segment_number; |
| 60 | } |
| 61 | commandline << dumpfile_ext; |
| 62 | commandline << "\""; |
| 63 | |
| 64 | { |
| 65 | GlobalNative gn; |
| 66 | |
| 67 | int pipefd[2] = {-1, -1}; |
| 68 | if (pipe(pipefd) < 0) { |
| 69 | LOG(LL_ERROR, LCF_DUMP, "Could not create a pipe to ffmpeg"); |
| 70 | return; |
| 71 | } |
| 72 | |
| 73 | ffmpeg_pid = fork(); |
| 74 | if (ffmpeg_pid < 0) { |
| 75 | LOG(LL_ERROR, LCF_DUMP, "Could not fork the ffmpeg process"); |
| 76 | close(pipefd[0]); |
| 77 | close(pipefd[1]); |
| 78 | return; |
| 79 | } |
| 80 | |
| 81 | if (ffmpeg_pid == 0) { |
| 82 | close(pipefd[1]); |
| 83 | dup2(pipefd[0], STDIN_FILENO); |
| 84 | close(pipefd[0]); |
| 85 | execlp("sh", "sh", "-c", commandline.str().c_str(), nullptr); |
| 86 | _exit(127); |
| 87 | } |
| 88 | |
| 89 | close(pipefd[0]); |
| 90 | ffmpeg_pipe = fdopen(pipefd[1], "w"); |
| 91 | if (!ffmpeg_pipe) { |
| 92 | LOG(LL_ERROR, LCF_DUMP, "Could not open the ffmpeg pipe stream"); |
| 93 | close(pipefd[1]); |
| 94 | waitpid(ffmpeg_pid, nullptr, 0); |
| 95 | ffmpeg_pid = -1; |
| 96 | return; |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | if (ScreenCapture::isInited()) { |
| 101 | initMuxer(); |
| 102 | } |
| 103 | |
| 104 | segment_number++; |
| 105 | /* Socket is already locked in frame.cpp */ |