-
-
Notifications
You must be signed in to change notification settings - Fork 0
Media Metadata
Load media through a reusable Client:
using var client = new Client("https://your-mirror.example");
using var media = await client.GetAsync(
"/films/drama/123-title.html",
cancellationToken);Or load one absolute page directly:
using var media = await Media.CreateAsync(
"https://your-mirror.example/films/drama/123-title.html",
cancellationToken: cancellationToken);Console.WriteLine(media.Id);
Console.WriteLine(media.Url);
Console.WriteLine(media.Origin);
Console.WriteLine(media.Name);
Console.WriteLine(media.OriginalName);
Console.WriteLine(media.Description);
Console.WriteLine(media.ReleaseYear);
Console.WriteLine(media.Thumbnail);
Console.WriteLine(media.ThumbnailHighQuality);
Console.WriteLine(media.Rating.Value);
Console.WriteLine(media.Rating.Votes);
Console.WriteLine(media.Format);
Console.WriteLine(media.Category);Rating is the internal aggregate score submitted by HDRezka users, not an
external service score. Rating.Value and Rating.Votes are nullable when the
page has no recognizable rating. External scores remain available through
Details.ExternalRatings.
An authenticated account can submit an integer score from 1 through 10:
var updated = await media.RateAsync(9, cancellationToken);
Console.WriteLine($"{updated.Value} ({updated.Votes})");The method also updates media.Rating. The website can reject a repeated vote
from the same account, which is reported as RatingException.
Names and OriginalNames preserve all parsed title variants, where Name is the
first localized title, while OriginalName is the last original title or
null
Alternative titles are separated only by a standalone slash surrounded by
spaces. Slashes that belong to a title, including double slashes such as in
.hack//Roots, remain part of the same title
MediaFormat describes the player shape:
MovieSeriesUnknown
MediaCategory is inferred from the catalog URL:
FilmSeriesCartoonAnimeShowUnknown
Format and category answer different questions; for example, an anime series
has MediaFormat.Series and MediaCategory.Anime
A media page can keep its metadata after the website loses its player data or temporarily starts restoring it:
Console.WriteLine(media.Playback.IsAvailable);
Console.WriteLine(media.Playback.Availability);
Console.WriteLine(media.Playback.Reason);PlaybackAvailability contains Available, TemporarilyUnavailable, and
Unavailable. When playback is unavailable, translator collections are empty
while the remaining media metadata and non-player operations stay accessible
Stream and episode operations throw PlaybackUnavailableException containing
the same PlaybackState without sending a player request
Details contains metadata that is already present in the downloaded media
page and therefore requires no additional request:
Console.WriteLine(media.Details.Tagline);
Console.WriteLine(media.Details.ReleaseDate);
Console.WriteLine(media.Details.Quality);
Console.WriteLine(media.Details.AgeRating);
Console.WriteLine(media.Details.Duration);
foreach (var country in media.Details.Countries)
{
Console.WriteLine(country.Name);
}
foreach (var person in media.Details.Cast)
{
Console.WriteLine($"{person.Name}: {person.Url}");
}The remaining collections expose genres, directors, linked collections, rankings, external ratings, recommendations, and series schedule entries. Nullable values indicate that the compatible website omitted the value or used an unrecognized format
foreach (var translator in media.TranslationOptions)
{
Console.WriteLine(
$"{translator.Id}: {translator.Name}; " +
$"Premium={translator.IsPremium}; " +
$"Camrip={translator.IsCamrip}; " +
$"Ads={translator.HasAds}; " +
$"DirectorCut={translator.IsDirectorCut}");
}Use TranslationOptions when variants must remain distinct because compatible
websites can return normal and director's-cut entries with the same numeric
identifier
The compatibility views are:
-
Translators— the first entry for each numeric ID -
TranslatorsByName— entries indexed by name without case sensitivity
Sort candidates using the configured priority:
var ordered = media.SortTranslators();Or override priority for one operation:
var ordered = media.SortTranslators(
preferred: [111, 56],
nonPreferred: [238]);See Configuration for persistent translator settings
OtherParts contains related titles in website order:
foreach (var part in media.OtherParts)
{
Console.WriteLine($"{part.Title}: {part.Url}");
}Load linked pages as complete media objects with bounded concurrency:
var parts = await media.GetOtherPartsAsync(cancellationToken);
foreach (var part in parts)
{
using (part)
{
Console.WriteLine(part.Name);
}
}var reference = media.Details.Cast[0];
var person = await client.People.GetAsync(reference, cancellationToken);
Console.WriteLine(person.OriginalName);
Console.WriteLine(person.BirthDateLabel);
foreach (var career in person.Careers)
{
Console.WriteLine($"{career.Name}: {career.Summary}");
}var trailer = await media.GetTrailerAsync(cancellationToken);
Console.WriteLine(trailer.SourceUrl);
var scheduleEntry = media.Details.Schedule[0];
var watched = await media.SetScheduleWatchedAsync(
scheduleEntry,
isWatched: true,
cancellationToken);media.AccountTier and media.IsPremiumAccount describe the session used
when the page was loaded; see Premium access before using
these values to make authorization decisions
Comments are loaded separately through the website AJAX endpoint:
var page = await media.Comments.GetPageAsync(page: 1);
var created = await media.Comments.AddAsync(
"A detailed review that follows the website rules",
cancellationToken);
var reply = await media.Comments.ReplyAsync(
created.Id,
"A reply to the review",
cancellationToken);
await media.Comments.DeleteAsync(reply.Id, cancellationToken);CommentPage contains nested comments in website order, current and total page
numbers, and the latest update identifier. Each comment exposes its parent
identifier, nesting depth, author, avatar, date label, text, like count, and
permalink. It also exposes the author profile, formatted HTML, current-account
like state, and available deletion or report controls
var like = await media.Comments.ToggleLikeAsync(comment.Id, cancellationToken);
var users = await media.Comments.GetLikeUsersAsync(comment.Id, cancellationToken);
await media.Comments.ReportAsync(
comment.Id,
issueId: 2,
description: "Spam links",
cancellationToken);Creation, replies, and deletion require an authenticated account and can be rejected by moderation, captcha, ownership checks, or comment rules. The live website exposes deletion for a user's own comments but does not expose comment editing, so the library intentionally has no edit method.