diff options
| author | Joel Klinghed <the_jk@spawned.biz> | 2021-11-17 22:34:57 +0100 |
|---|---|---|
| committer | Joel Klinghed <the_jk@spawned.biz> | 2021-11-17 22:34:57 +0100 |
| commit | 6232d13f5321b87ddf12a1aa36b4545da45f173d (patch) | |
| tree | 23f3316470a14136debd9d02f9e920ca2b06f4cc /src/video.cc | |
Travel3: Simple image and video display site
Reads the images and videos from filesystem and builds a site in
memroy.
Diffstat (limited to 'src/video.cc')
| -rw-r--r-- | src/video.cc | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/src/video.cc b/src/video.cc new file mode 100644 index 0000000..110bd4a --- /dev/null +++ b/src/video.cc @@ -0,0 +1,171 @@ +#include "common.hh" + +#include "strutil.hh" +#include "timezone.hh" +#include "video.hh" + +#if HAVE_MEDIAINFO +#include <MediaInfo/MediaInfo.h> +#endif + +namespace { + +class VideoImpl : public Video { +public: + VideoImpl(uint64_t width, uint64_t height) + : width_(width), height_(height) {} + + uint64_t width() const override { + return width_; + } + + uint64_t height() const override { + return height_; + } + + double length() const override { + return length_; + } + + Location location() const override { + return location_; + } + + Date date() const override { + return date_; + } + + void set_length(double length) { + length_ = length; + } + + void set_location(Location location) { + location_ = location; + } + + void set_date(Date date) { + date_ = date; + } + +private: + uint64_t width_; + uint64_t height_; + double length_{0.0}; + Location location_; + Date date_; +}; + +#if HAVE_MEDIAINFO +bool parse_location(std::string const& str, Location* location) { + auto end = str.find('/'); + if (end == std::string::npos) + return false; + char* latend = nullptr; + location->lat = strtod(str.c_str(), &latend); + if (!latend) + return false; + char* lngend = nullptr; + location->lng = strtod(latend, &lngend); + if (!lngend) + return false; + if (lngend != str.c_str() + end) + return false; + return true; +} +#endif + +} // namespace + +std::unique_ptr<Video> Video::load(std::filesystem::path const& path, + Timezone const* timezone) { +#if HAVE_MEDIAINFO + MediaInfoLib::MediaInfo info; +#if defined(UNICODE) || defined (_UNICODE) + std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>, wchar_t> convert; + if (info.Open(convert.from_bytes(path))) { + auto width = str::parse_uint64( + convert.to_bytes(info.Get(MediaInfoLib::Stream_Video, 0, L"Width"))); + auto height = str::parse_uint64( + convert.to_bytes(info.Get(MediaInfoLib::Stream_Video, 0, L"Height"))); + if (width && height) { + std::optional<Location> location; + auto video = std::make_unique<VideoImpl>(*width, *height); + auto duration = str::parse_uint64( + convert.to_bytes( + info.Get(MediaInfoLib::Stream_Video, 0, L"Duration"))); + if (duration) + video->set_length(*duration / 1000.0); + { + Location tmp; + if (parse_location( + convert.to_bytes( + info.Get(MediaInfoLib::Stream_General, 0, L"xyz")), + &tmp)) { + location = tmp; + video->set_location(tmp); + } + } + { + auto date = Date::from_format( + "UTC %Y-%m-%d %H:%M:%S", + convert.to_bytes( + info.Get(MediaInfoLib::Stream_General, 0, L"Encoded_Date")), + false); + if (!date.empty()) { + video->set_date(date.value()); + if (location) { + auto local_time = timezone->get_local_time(location->lat, + location->lng, + date.value()); + if (local_time) + video->set_date(local_time.value()); + } + } + } + return video; + } + } +#else // UNICODE || _UNICODE + if (info.Open(path)) { + auto width = str::parse_uint64( + info.Get(MediaInfoLib::Stream_Video, 0, "Width")); + auto height = str::parse_uint64( + info.Get(MediaInfoLib::Stream_Video, 0, "Height")); + if (width && height) { + auto video = std::make_unique<VideoImpl>(*width, *height); + auto duration = str::parse_uint64( + info.Get(MediaInfoLib::Stream_Video, 0, "Duration")); + if (duration) + video->set_length(*duration / 1000.0); + std::optional<Location> location; + { + Location tmp; + if (parse_location(info.Get(MediaInfoLib::Stream_General, 0, "xyz"), + &tmp)) { + location = tmp; + video->set_location(tmp); + } + } + { + auto date = Date::from_format( + "UTC %Y-%m-%d %H:%M:%S", + info.Get(MediaInfoLib::Stream_General, 0, "Encoded_Date"), + false); + if (!date.empty()) { + video->set_date(date.value()); + if (location) { + auto local_time = timezone->get_local_time(location->lat, + location->lng, + date.value()); + if (local_time) + video->set_date(local_time.value()); + } + } + } + return video; + } + } +#endif // UNICODE || _UNICODE +#endif // HAVE_MEDIAINFO + return nullptr; +} |
