Я хочу создать небольшой патч для программы. Я мало что знаю о С.
Когда моя функция get_streamlink
вернула buffer
, следующему коду не удалось получить видео по m3u8
URL-адресу. Когда функция возвращает статический URL-адрес, видео показывает успех. В обоих случаях URL-адреса и следующий код одинаковы. В чем дело?
UPD: Спасибо за комментарии. Проблема с \n
из fgets
.
static char *get_streamlink(const char *url) {
char *template = "streamlink %s best --stream-url";
char *buffer = (char *)malloc(5060);
FILE *pPipe;
struct dstr command = {0};
dstr_catf(&command, template, url);
pPipe = _popen(command.array, "rt");
dstr_free(&command);
while (fgets(buffer, 5060, pPipe)) {
puts(buffer);
}
int endOfFileVal = feof(pPipe);
int closeReturnVal = _pclose(pPipe);
// failed
return buffer;
// OK
// return "https://video-weaver.arn03.hls.ttvnw.net/v1/playlist/CvAEXGd8OH7.....m3u8";
}
static void add_file(struct vlc_source *c, media_file_array_t *new_files,
const char *path, int network_caching, int track_index,
int subtitle_index, bool subtitle_enable,
const char *hw_value, bool skip_b_frames)
{
struct media_file_data data;
struct dstr new_path = {0};
libvlc_media_t *new_media;
bool is_url = path && strstr(path, "://") != NULL;
dstr_copy(&new_path, path);
#ifdef _WIN32
if (!is_url)
dstr_replace(&new_path, "/", "\\");
#endif
dstr_copy(&new_path, get_streamlink(new_path.array));
path = new_path.array;
new_media = get_media(&c->files, path);
//...
}
Что делает dstr_copy
?
«Следующему коду не удалось загрузить видео». Содержит ли буфер правильный контент? Кстати: какое содержание последней строки вы читаете с помощью fgets
, отбрасывая все строки, кроме последней.
@Gerhardh, согласно отладке, буфер имеет тот же URL-адрес. Исходный код без моей функции здесь: github.com/obsproject/obs-studio/tree/master/plugins/vlc-video
Знаете ли вы, что fgets
оставляет \n
в конце строки?
@Gerhardh, как читать без \n
или потом удалить?
Выводит ли while (fgets(buffer, 5060, pPipe)) { puts(buffer); }
две новые строки? Один остался от fgets()
и один добавлен puts()
?
Пожалуйста, удалите весь код, который не имеет отношения к использованию popen
. Пожалуйста, создайте минимальный воспроизводимый пример.
См. Удаление завершающего символа новой строки из ввода fgets()
большое спасибо! Оно работает. Проблема с \n
Вам нужно удалить завершающие \n
/\r\n
.
Поскольку вы используете нестандартную функцию _popen
, вы также можете использовать другое нестандартное расширение в MSVC: конструктор basic_ifstream
, принимающий FILE*
. После этого вы можете использовать std::getline
во входном потоке.
#include <cstdio>
#include <fstream>
#include <iostream>
#include <string>
std::ifstream Popen(const char* command) {
auto fp = _popen(command, "rt");
return std::ifstream(fp); // construct the ifstream using a FILE*
}
int main() {
auto is = Popen("dir");
std::string line;
while (std::getline(is, line)) {
std::cout << line << '\n';
}
}
Я предлагаю показывать значение
path
вadd_file
как в хорошем, так и в плохом случае, а также проверять наличие невидимых символов. (Может быть, завершающая новая строка?)