DummyVideoProvider::DummyVideoProvider(agi::fs::path const& filename) { if (!boost::starts_with(filename.string(), "?dummy")) throw agi::fs::FileNotFound(std::string("Attempted creating dummy video provider with non-dummy filename")); std::vector<std::string> toks; auto const& fields = filename.string().substr(7); boost::split(toks, fields, boost::is_any_of(":")); if (toks.size() != 8) throw VideoOpenError("Too few fields in dummy video parameter list"); size_t i = 0; double fps; int frames, width, height, red, green, blue; using agi::util::try_parse; if (!try_parse(toks[i++], &fps)) throw VideoOpenError("Unable to parse fps field in dummy video parameter list"); if (!try_parse(toks[i++], &frames)) throw VideoOpenError("Unable to parse framecount field in dummy video parameter list"); if (!try_parse(toks[i++], &width)) throw VideoOpenError("Unable to parse width field in dummy video parameter list"); if (!try_parse(toks[i++], &height)) throw VideoOpenError("Unable to parse height field in dummy video parameter list"); if (!try_parse(toks[i++], &red)) throw VideoOpenError("Unable to parse red colour field in dummy video parameter list"); if (!try_parse(toks[i++], &green)) throw VideoOpenError("Unable to parse green colour field in dummy video parameter list"); if (!try_parse(toks[i++], &blue)) throw VideoOpenError("Unable to parse blue colour field in dummy video parameter list"); bool pattern = toks[i] == "c"; Create(fps, frames, width, height, red, green, blue, pattern); }
bool Project::DoLoadSubtitles(agi::fs::path const& path, std::string encoding, ProjectProperties &properties) { try { if (encoding.empty()) encoding = CharSetDetect::GetEncoding(path); } catch (agi::UserCancelException const&) { return false; } catch (agi::fs::FileNotFound const&) { config::mru->Remove("Subtitle", path); ShowError(path.string() + " not found."); return false; } if (encoding != "binary") { // Try loading as timecodes and keyframes first since we can't // distinguish them based on filename alone, and just ignore failures // rather than trying to differentiate between malformed timecodes // files and things that aren't timecodes files at all try { DoLoadTimecodes(path); return false; } catch (...) { } try { DoLoadKeyframes(path); return false; } catch (...) { } } try { properties = context->subsController->Load(path, encoding); } catch (agi::UserCancelException const&) { return false; } catch (agi::fs::FileNotFound const&) { config::mru->Remove("Subtitle", path); ShowError(path.string() + " not found."); return false; } catch (agi::Exception const& e) { ShowError(e.GetMessage()); return false; } catch (std::exception const& e) { ShowError(std::string(e.what())); return false; } catch (...) { ShowError(wxString("Unknown error")); return false; } Selection sel; AssDialogue *active_line = nullptr; if (!context->ass->Events.empty()) { int row = mid<int>(0, properties.active_row, context->ass->Events.size() - 1); active_line = &*std::next(context->ass->Events.begin(), row); sel.insert(active_line); } context->selectionController->SetSelectionAndActive(std::move(sel), active_line); context->subsGrid->ScrollTo(properties.scroll_position); return true; }
/// @brief Generates an unique name for the ffms2 index file and prepares the cache folder if it doesn't exist /// @param filename The name of the source file /// @return Returns the generated filename. agi::fs::path FFmpegSourceProvider::GetCacheFilename(agi::fs::path const& filename) { // Get the size of the file to be hashed uintmax_t len = agi::fs::Size(filename); // Get the hash of the filename boost::crc_32_type hash; hash.process_bytes(filename.string().c_str(), filename.string().size()); // Generate the filename auto result = config::path->Decode("?local/ffms2cache/" + std::to_string(hash.checksum()) + "_" + std::to_string(len) + "_" + std::to_string(agi::fs::ModifiedTime(filename)) + ".ffindex"); // Ensure that folder exists agi::fs::CreateDirectory(result.parent_path()); return result; }
std::unique_ptr<VideoProvider> VideoProviderFactory::GetProvider(agi::fs::path const& video_file, std::string const& colormatrix) { std::vector<std::string> factories = GetClasses(OPT_GET("Video/Provider")->GetString()); factories.insert(factories.begin(), "YUV4MPEG"); factories.insert(factories.begin(), "Dummy"); bool found = false; bool supported = false; std::string errors; errors.reserve(1024); for (auto const& factory : factories) { std::string err; try { auto provider = Create(factory, video_file, colormatrix); LOG_I("manager/video/provider") << factory << ": opened " << video_file; return provider->WantsCaching() ? agi::util::make_unique<VideoProviderCache>(std::move(provider)) : std::move(provider); } catch (agi::fs::FileNotFound const&) { err = "file not found."; // Keep trying other providers as this one may just not be able to // open a valid path } catch (VideoNotSupported const&) { found = true; err = "video is not in a supported format."; } catch (VideoOpenError const& ex) { supported = true; err = ex.GetMessage(); } catch (agi::vfr::Error const& ex) { supported = true; err = ex.GetMessage(); } errors += factory + ": " + err + "\n"; LOG_D("manager/video/provider") << factory << ": " << err; } // No provider could open the file LOG_E("manager/video/provider") << "Could not open " << video_file; std::string msg = "Could not open " + video_file.string() + ":\n" + errors; if (!found) throw agi::fs::FileNotFound(video_file.string()); if (!supported) throw VideoNotSupported(msg); throw VideoOpenError(msg); }
std::unique_ptr<VideoProvider> VideoProviderFactory::GetProvider(agi::fs::path const& filename, std::string const& colormatrix, agi::BackgroundRunner *br) { auto preferred = OPT_GET("Video/Provider")->GetString(); auto sorted = GetSorted(boost::make_iterator_range(std::begin(providers), std::end(providers)), preferred); bool found = false; bool supported = false; std::string errors; errors.reserve(1024); for (auto factory : sorted) { std::string err; try { auto provider = factory->create(filename, colormatrix, br); if (!provider) continue; LOG_I("manager/video/provider") << factory->name << ": opened " << filename; return provider->WantsCaching() ? CreateCacheVideoProvider(std::move(provider)) : std::move(provider); } catch (agi::fs::FileNotFound const&) { err = "file not found."; // Keep trying other providers as this one may just not be able to // open a valid path } catch (VideoNotSupported const&) { found = true; err = "video is not in a supported format."; } catch (VideoOpenError const& ex) { supported = true; err = ex.GetMessage(); } catch (agi::vfr::Error const& ex) { supported = true; err = ex.GetMessage(); } errors += std::string(factory->name) + ": " + err + "\n"; LOG_D("manager/video/provider") << factory->name << ": " << err; } // No provider could open the file LOG_E("manager/video/provider") << "Could not open " << filename; std::string msg = "Could not open " + filename.string() + ":\n" + errors; if (!found) throw agi::fs::FileNotFound(filename.string()); if (!supported) throw VideoNotSupported(msg); throw VideoOpenError(msg); }
bool LoadFile(lua_State *L, agi::fs::path const& filename) { std::unique_ptr<std::istream> file(agi::io::Open(filename, true)); file->seekg(0, std::ios::end); size_t size = file->tellg(); file->seekg(0, std::ios::beg); std::string buff; buff.resize(size); // Discard the BOM if present file->read(&buff[0], 3); size_t start = file->gcount(); if (start == 3 && buff[0] == -17 && buff[1] == -69 && buff[2] == -65) { buff.resize(size - 3); start = 0; } file->read(&buff[start], size - start); if (!agi::fs::HasExtension(filename, "moon")) return luaL_loadbuffer(L, &buff[0], buff.size(), filename.string().c_str()) == 0; // We have a MoonScript file, so we need to load it with that // It might be nice to have a dedicated lua state for compiling // MoonScript to Lua if (luaL_dostring(L, "return require('moonscript').loadstring")) return false; // Leaves error message on stack lua_pushlstring(L, &buff[0], buff.size()); lua_pushstring(L, filename.string().c_str()); if (lua_pcall(L, 2, 2, 0)) return false; // Leaves error message on stack // loadstring returns nil, error on error or a function on success if (lua_isnil(L, 1)) { lua_remove(L, 1); return false; } lua_pop(L, 1); // Remove the extra nil for the stackchecker return true; }
bool TXTSubtitleFormat::CanWriteFile(agi::fs::path const& filename) const { auto str = filename.string(); return boost::iends_with(str, ".txt") && !(boost::iends_with(str, ".encore.txt") || boost::iends_with(str, ".transtation.txt")); }