void Project::LoadUnloadFiles(ProjectProperties properties) { auto load_linked = OPT_GET("App/Auto/Load Linked Files")->GetInt(); if (!load_linked) return; auto audio = context->path->MakeAbsolute(properties.audio_file, "?script"); auto video = context->path->MakeAbsolute(properties.video_file, "?script"); auto timecodes = context->path->MakeAbsolute(properties.timecodes_file, "?script"); auto keyframes = context->path->MakeAbsolute(properties.keyframes_file, "?script"); if (video == video_file && audio == audio_file && keyframes == keyframes_file && timecodes == timecodes_file) return; if (load_linked == 2) { wxString str = _("Do you want to load/unload the associated files?"); str += "\n"; auto append_file = [&](agi::fs::path const& p, wxString const& unload, wxString const& load) { if (p.empty()) str += "\n" + unload; else str += "\n" + agi::wxformat(load, p); }; if (audio != audio_file) append_file(audio, _("Unload audio"), _("Load audio file: %s")); if (video != video_file) append_file(video, _("Unload video"), _("Load video file: %s")); if (timecodes != timecodes_file) append_file(timecodes, _("Unload timecodes"), _("Load timecodes file: %s")); if (keyframes != keyframes_file) append_file(keyframes, _("Unload keyframes"), _("Load keyframes file: %s")); if (wxMessageBox(str, _("(Un)Load files?"), wxYES_NO | wxCENTRE, context->parent) != wxYES) return; } bool loaded_video = false; if (video != video_file) { if (video.empty()) CloseVideo(); else if ((loaded_video = DoLoadVideo(video))) { auto vc = context->videoController.get(); vc->JumpToFrame(properties.video_position); auto ar_mode = static_cast<AspectRatio>(properties.ar_mode); if (ar_mode == AspectRatio::Custom) vc->SetAspectRatio(properties.ar_value); else vc->SetAspectRatio(ar_mode); context->videoDisplay->SetZoom(properties.video_zoom); } } if (!timecodes.empty()) LoadTimecodes(timecodes); if (!keyframes.empty()) LoadKeyframes(keyframes); if (audio != audio_file) { if (audio.empty()) CloseAudio(); else DoLoadAudio(audio, false); } else if (loaded_video && OPT_GET("Video/Open Audio")->GetBool() && audio_file != video_file && video_provider->HasAudio()) DoLoadAudio(video, true); }
void Project::LoadList(std::vector<agi::fs::path> const& files) { // Keep these lists sorted // Video formats const char *videoList[] = { ".asf", ".avi", ".avs", ".d2v", ".m2ts", ".m4v", ".mkv", ".mov", ".mp4", ".mpeg", ".mpg", ".ogm", ".rm", ".rmvb", ".ts", ".webm" ".wmv", ".y4m", ".yuv" }; // Subtitle formats const char *subsList[] = { ".ass", ".srt", ".ssa", ".sub", ".ttxt" }; // Audio formats const char *audioList[] = { ".aac", ".ac3", ".ape", ".dts", ".flac", ".m4a", ".mka", ".mp3", ".ogg", ".w64", ".wav", ".wma" }; auto search = [](const char **begin, const char **end, std::string const& str) { return std::binary_search(begin, end, str.c_str(), [](const char *a, const char *b) { return strcmp(a, b) < 0; }); }; agi::fs::path audio, video, subs, timecodes, keyframes; for (auto file : files) { if (file.is_relative()) file = absolute(file); if (!agi::fs::FileExists(file)) continue; auto ext = file.extension().string(); boost::to_lower(ext); // Could be subtitles, keyframes or timecodes, so try loading as each if (ext == ".txt" || ext == ".log") { if (timecodes.empty()) { try { DoLoadTimecodes(file); timecodes = file; continue; } catch (...) { } } if (keyframes.empty()) { try { DoLoadKeyframes(file); keyframes = file; continue; } catch (...) { } } if (subs.empty() && ext != ".log") subs = file; continue; } if (subs.empty() && search(std::begin(subsList), std::end(subsList), ext)) subs = file; if (video.empty() && search(std::begin(videoList), std::end(videoList), ext)) video = file; if (audio.empty() && search(std::begin(audioList), std::end(audioList), ext)) audio = file; } ProjectProperties properties; if (!subs.empty()) { if (!DoLoadSubtitles(subs, "", properties)) subs.clear(); } if (!video.empty() && DoLoadVideo(video)) { double dar = video_provider->GetDAR(); if (dar > 0) context->videoController->SetAspectRatio(dar); else context->videoController->SetAspectRatio(AspectRatio::Default); context->videoController->JumpToFrame(0); // We loaded these earlier, but loading video unloaded them // Non-Do version of Load in case they've vanished or changed between // then and now if (!timecodes.empty()) LoadTimecodes(timecodes); if (!keyframes.empty()) LoadKeyframes(keyframes); } if (!audio.empty()) DoLoadAudio(audio, false); else if (OPT_GET("Video/Open Audio")->GetBool() && audio_file != video_file) DoLoadAudio(video_file, true); if (!subs.empty()) LoadUnloadFiles(properties); }
void FrameMain::OnSubtitlesOpen() { UpdateTitle(); auto vc = context->videoController; /// @todo figure out how to move this to the relevant controllers without /// prompting for each file loaded/unloaded // Load stuff from the new script auto video = config::path->MakeAbsolute(context->ass->GetScriptInfo("Video File"), "?script"); auto vfr = config::path->MakeAbsolute(context->ass->GetScriptInfo("VFR File"), "?script"); auto keyframes = config::path->MakeAbsolute(context->ass->GetScriptInfo("Keyframes File"), "?script"); auto audio = config::path->MakeAbsolute(context->ass->GetScriptInfo("Audio URI"), "?script"); bool videoChanged = !blockVideoLoad && video != vc->GetVideoName(); bool timecodesChanged = vfr != vc->GetTimecodesName(); bool keyframesChanged = keyframes != vc->GetKeyFramesName(); bool audioChanged = !blockAudioLoad && audio != context->audioController->GetAudioURL(); // Check if there is anything to change int autoLoadMode = OPT_GET("App/Auto/Load Linked Files")->GetInt(); if (autoLoadMode == 0 || (!videoChanged && !timecodesChanged && !keyframesChanged && !audioChanged)) { SetDisplayMode(1, 1); return; } if (autoLoadMode == 2) { if (wxMessageBox(_("Do you want to load/unload the associated files?"), _("(Un)Load files?"), wxYES_NO | wxCENTRE, this) != wxYES) { SetDisplayMode(1, 1); if (vc->IsLoaded() && vc->GetProvider()->GetColorSpace() != context->ass->GetScriptInfo("YCbCr Matrix")) vc->Reload(); return; } } if (audioChanged) blockAudioLoad = true; // Video if (videoChanged) { vc->SetVideo(video); if (vc->IsLoaded()) { vc->JumpToFrame(context->ass->GetUIStateAsInt("Video Position")); std::string arString = context->ass->GetUIState("Video Aspect Ratio"); if (boost::starts_with(arString, "c")) { double ar = 0.; agi::util::try_parse(arString.substr(1), &ar); vc->SetAspectRatio(ar); } else { int ar = 0; if (agi::util::try_parse(arString, &ar) && ar >= 0 && ar < 4) vc->SetAspectRatio((AspectRatio)ar); } double videoZoom = 0.; if (agi::util::try_parse(context->ass->GetUIState("Video Zoom Percent"), &videoZoom)) context->videoDisplay->SetZoom(videoZoom); } } else if (vc->IsLoaded() && vc->GetProvider()->GetColorSpace() != context->ass->GetScriptInfo("YCbCr Matrix")) vc->Reload(); vc->LoadTimecodes(vfr); vc->LoadKeyframes(keyframes); // Audio if (audioChanged) { blockAudioLoad = false; try { if (audio.empty()) context->audioController->CloseAudio(); else context->audioController->OpenAudio(audio); } catch (agi::UserCancelException const&) { } catch (agi::fs::FileSystemError const& err) { wxMessageBox(to_wx(err.GetMessage()), "Error opening audio", wxOK | wxICON_ERROR | wxCENTER, this); } } SetDisplayMode(1, 1); }