diff --git a/YoutubeExplode.Converter/ConversionFormat.cs b/YoutubeExplode.Converter/ConversionFormat.cs
index c911bfa3..4f4fbebd 100644
--- a/YoutubeExplode.Converter/ConversionFormat.cs
+++ b/YoutubeExplode.Converter/ConversionFormat.cs
@@ -8,23 +8,18 @@ namespace YoutubeExplode.Converter;
/// Encapsulates conversion media format.
///
[Obsolete("Use YoutubeExplode.Videos.Streams.Container instead"), ExcludeFromCodeCoverage]
-public readonly struct ConversionFormat
+public readonly struct ConversionFormat(string name)
{
///
/// Format name.
///
- public string Name { get; }
+ public string Name { get; } = name;
///
/// Whether this format is a known audio-only format.
///
public bool IsAudioOnly => new Container(Name).IsAudioOnly();
- ///
- /// Initializes an instance of .
- ///
- public ConversionFormat(string name) => Name = name;
-
///
public override string ToString() => Name;
}
diff --git a/YoutubeExplode.Converter/ConversionRequest.cs b/YoutubeExplode.Converter/ConversionRequest.cs
index 876c6b4e..3fcb9f9e 100644
--- a/YoutubeExplode.Converter/ConversionRequest.cs
+++ b/YoutubeExplode.Converter/ConversionRequest.cs
@@ -7,22 +7,39 @@ namespace YoutubeExplode.Converter;
///
/// Conversion options.
///
-public class ConversionRequest
+public class ConversionRequest(
+ string ffmpegCliFilePath,
+ string outputFilePath,
+ Container container,
+ ConversionPreset preset
+)
{
+ ///
+ /// Initializes an instance of .
+ ///
+ [Obsolete("Use the other constructor overload"), ExcludeFromCodeCoverage]
+ public ConversionRequest(
+ string ffmpegCliFilePath,
+ string outputFilePath,
+ ConversionFormat format,
+ ConversionPreset preset
+ )
+ : this(ffmpegCliFilePath, outputFilePath, new Container(format.Name), preset) { }
+
///
/// Path to the FFmpeg CLI.
///
- public string FFmpegCliFilePath { get; }
+ public string FFmpegCliFilePath { get; } = ffmpegCliFilePath;
///
/// Output file path.
///
- public string OutputFilePath { get; }
+ public string OutputFilePath { get; } = outputFilePath;
///
/// Output container.
///
- public Container Container { get; }
+ public Container Container { get; } = container;
///
/// Output format.
@@ -33,33 +50,5 @@ public class ConversionRequest
///
/// Encoder preset.
///
- public ConversionPreset Preset { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public ConversionRequest(
- string ffmpegCliFilePath,
- string outputFilePath,
- Container container,
- ConversionPreset preset
- )
- {
- FFmpegCliFilePath = ffmpegCliFilePath;
- OutputFilePath = outputFilePath;
- Container = container;
- Preset = preset;
- }
-
- ///
- /// Initializes an instance of .
- ///
- [Obsolete("Use the other constructor overload"), ExcludeFromCodeCoverage]
- public ConversionRequest(
- string ffmpegCliFilePath,
- string outputFilePath,
- ConversionFormat format,
- ConversionPreset preset
- )
- : this(ffmpegCliFilePath, outputFilePath, new Container(format.Name), preset) { }
+ public ConversionPreset Preset { get; } = preset;
}
diff --git a/YoutubeExplode.Converter/ConversionRequestBuilder.cs b/YoutubeExplode.Converter/ConversionRequestBuilder.cs
index f6a7c7ed..266c7fb4 100644
--- a/YoutubeExplode.Converter/ConversionRequestBuilder.cs
+++ b/YoutubeExplode.Converter/ConversionRequestBuilder.cs
@@ -9,21 +9,14 @@ namespace YoutubeExplode.Converter;
///
/// Builder for .
///
-public class ConversionRequestBuilder
+public class ConversionRequestBuilder(string outputFilePath)
{
- private readonly string _outputFilePath;
-
private string? _ffmpegCliFilePath;
private Container? _container;
private ConversionPreset _preset;
- ///
- /// Initializes an instance of .
- ///
- public ConversionRequestBuilder(string outputFilePath) => _outputFilePath = outputFilePath;
-
private Container GetDefaultContainer() =>
- new(Path.GetExtension(_outputFilePath).TrimStart('.').NullIfWhiteSpace() ?? "mp4");
+ new(Path.GetExtension(outputFilePath).TrimStart('.').NullIfWhiteSpace() ?? "mp4");
///
/// Sets the path to the FFmpeg CLI.
@@ -77,7 +70,7 @@ public ConversionRequestBuilder SetPreset(ConversionPreset preset)
public ConversionRequest Build() =>
new(
_ffmpegCliFilePath ?? FFmpeg.GetFilePath(),
- _outputFilePath,
+ outputFilePath,
_container ?? GetDefaultContainer(),
_preset
);
diff --git a/YoutubeExplode/Channels/Channel.cs b/YoutubeExplode/Channels/Channel.cs
index 3bf472d0..cfd0f638 100644
--- a/YoutubeExplode/Channels/Channel.cs
+++ b/YoutubeExplode/Channels/Channel.cs
@@ -7,29 +7,19 @@ namespace YoutubeExplode.Channels;
///
/// Metadata associated with a YouTube channel.
///
-public class Channel : IChannel
+public class Channel(ChannelId id, string title, IReadOnlyList thumbnails) : IChannel
{
///
- public ChannelId Id { get; }
+ public ChannelId Id { get; } = id;
///
public string Url => $"https://www.youtube.com/channel/{Id}";
///
- public string Title { get; }
+ public string Title { get; } = title;
///
- public IReadOnlyList Thumbnails { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public Channel(ChannelId id, string title, IReadOnlyList thumbnails)
- {
- Id = id;
- Title = title;
- Thumbnails = thumbnails;
- }
+ public IReadOnlyList Thumbnails { get; } = thumbnails;
///
[ExcludeFromCodeCoverage]
diff --git a/YoutubeExplode/Channels/ChannelClient.cs b/YoutubeExplode/Channels/ChannelClient.cs
index 76a9c367..c5b757e1 100644
--- a/YoutubeExplode/Channels/ChannelClient.cs
+++ b/YoutubeExplode/Channels/ChannelClient.cs
@@ -15,19 +15,9 @@ namespace YoutubeExplode.Channels;
///
/// Operations related to YouTube channels.
///
-public class ChannelClient
+public class ChannelClient(HttpClient http)
{
- private readonly HttpClient _http;
- private readonly ChannelController _controller;
-
- ///
- /// Initializes an instance of .
- ///
- public ChannelClient(HttpClient http)
- {
- _http = http;
- _controller = new ChannelController(http);
- }
+ private readonly ChannelController _controller = new(http);
private Channel Get(ChannelPage channelPage)
{
@@ -118,6 +108,6 @@ public IAsyncEnumerable GetUploadsAsync(
{
// Replace 'UC' in the channel ID with 'UU'
var playlistId = "UU" + channelId.Value[2..];
- return new PlaylistClient(_http).GetVideosAsync(playlistId, cancellationToken);
+ return new PlaylistClient(http).GetVideosAsync(playlistId, cancellationToken);
}
}
diff --git a/YoutubeExplode/Common/Author.cs b/YoutubeExplode/Common/Author.cs
index ecfbbc9c..559f594e 100644
--- a/YoutubeExplode/Common/Author.cs
+++ b/YoutubeExplode/Common/Author.cs
@@ -7,12 +7,12 @@ namespace YoutubeExplode.Common;
///
/// Reference to a channel that owns a specific YouTube video or playlist.
///
-public class Author
+public class Author(ChannelId channelId, string channelTitle)
{
///
/// Channel ID.
///
- public ChannelId ChannelId { get; }
+ public ChannelId ChannelId { get; } = channelId;
///
/// Channel URL.
@@ -22,21 +22,12 @@ public class Author
///
/// Channel title.
///
- public string ChannelTitle { get; }
+ public string ChannelTitle { get; } = channelTitle;
///
[Obsolete("Use ChannelTitle instead."), ExcludeFromCodeCoverage]
public string Title => ChannelTitle;
- ///
- /// Initializes an instance of .
- ///
- public Author(ChannelId channelId, string channelTitle)
- {
- ChannelId = channelId;
- ChannelTitle = channelTitle;
- }
-
///
[ExcludeFromCodeCoverage]
public override string ToString() => ChannelTitle;
diff --git a/YoutubeExplode/Common/Batch.cs b/YoutubeExplode/Common/Batch.cs
index f6187e3e..c9645ad4 100644
--- a/YoutubeExplode/Common/Batch.cs
+++ b/YoutubeExplode/Common/Batch.cs
@@ -6,18 +6,13 @@ namespace YoutubeExplode.Common;
///
/// Generic collection of items returned by a single request.
///
-public class Batch
+public class Batch(IReadOnlyList items)
where T : IBatchItem
{
///
/// Items included in the batch.
///
- public IReadOnlyList Items { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public Batch(IReadOnlyList items) => Items = items;
+ public IReadOnlyList Items { get; } = items;
}
internal static class Batch
diff --git a/YoutubeExplode/Common/Resolution.cs b/YoutubeExplode/Common/Resolution.cs
index f9429206..3dc2d5a3 100644
--- a/YoutubeExplode/Common/Resolution.cs
+++ b/YoutubeExplode/Common/Resolution.cs
@@ -6,32 +6,23 @@ namespace YoutubeExplode.Common;
///
/// Resolution of an image or a video.
///
-public readonly partial struct Resolution
+public readonly partial struct Resolution(int width, int height)
{
///
/// Viewport width, measured in pixels.
///
- public int Width { get; }
+ public int Width { get; } = width;
///
/// Viewport height, measured in pixels.
///
- public int Height { get; }
+ public int Height { get; } = height;
///
/// Viewport area (i.e. width multiplied by height).
///
public int Area => Width * Height;
- ///
- /// Initializes an instance of .
- ///
- public Resolution(int width, int height)
- {
- Width = width;
- Height = height;
- }
-
///
[ExcludeFromCodeCoverage]
public override string ToString() => $"{Width}x{Height}";
diff --git a/YoutubeExplode/Common/Thumbnail.cs b/YoutubeExplode/Common/Thumbnail.cs
index ccaab477..4c58498f 100644
--- a/YoutubeExplode/Common/Thumbnail.cs
+++ b/YoutubeExplode/Common/Thumbnail.cs
@@ -9,26 +9,17 @@ namespace YoutubeExplode.Common;
///
/// Thumbnail image.
///
-public partial class Thumbnail
+public partial class Thumbnail(string url, Resolution resolution)
{
///
/// Thumbnail URL.
///
- public string Url { get; }
+ public string Url { get; } = url;
///
/// Thumbnail resolution.
///
- public Resolution Resolution { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public Thumbnail(string url, Resolution resolution)
- {
- Url = url;
- Resolution = resolution;
- }
+ public Resolution Resolution { get; } = resolution;
///
[ExcludeFromCodeCoverage]
diff --git a/YoutubeExplode/Exceptions/PlaylistUnavailableException.cs b/YoutubeExplode/Exceptions/PlaylistUnavailableException.cs
index 696ad1b1..a7d1d8aa 100644
--- a/YoutubeExplode/Exceptions/PlaylistUnavailableException.cs
+++ b/YoutubeExplode/Exceptions/PlaylistUnavailableException.cs
@@ -3,11 +3,4 @@ namespace YoutubeExplode.Exceptions;
///
/// Exception thrown when the requested playlist is unavailable.
///
-public class PlaylistUnavailableException : YoutubeExplodeException
-{
- ///
- /// Initializes an instance of .
- ///
- public PlaylistUnavailableException(string message)
- : base(message) { }
-}
+public class PlaylistUnavailableException(string message) : YoutubeExplodeException(message);
diff --git a/YoutubeExplode/Exceptions/RequestLimitExceededException.cs b/YoutubeExplode/Exceptions/RequestLimitExceededException.cs
index a52cf053..8b540ac9 100644
--- a/YoutubeExplode/Exceptions/RequestLimitExceededException.cs
+++ b/YoutubeExplode/Exceptions/RequestLimitExceededException.cs
@@ -3,11 +3,4 @@ namespace YoutubeExplode.Exceptions;
///
/// Exception thrown when YouTube denies a request because the client has exceeded rate limit.
///
-public class RequestLimitExceededException : YoutubeExplodeException
-{
- ///
- /// Initializes an instance of .
- ///
- public RequestLimitExceededException(string message)
- : base(message) { }
-}
+public class RequestLimitExceededException(string message) : YoutubeExplodeException(message);
diff --git a/YoutubeExplode/Exceptions/VideoRequiresPurchaseException.cs b/YoutubeExplode/Exceptions/VideoRequiresPurchaseException.cs
index 6325c2c8..32bcc95d 100644
--- a/YoutubeExplode/Exceptions/VideoRequiresPurchaseException.cs
+++ b/YoutubeExplode/Exceptions/VideoRequiresPurchaseException.cs
@@ -5,16 +5,11 @@ namespace YoutubeExplode.Exceptions;
///
/// Exception thrown when the requested video requires purchase.
///
-public class VideoRequiresPurchaseException : VideoUnplayableException
+public class VideoRequiresPurchaseException(string message, VideoId previewVideoId)
+ : VideoUnplayableException(message)
{
///
/// ID of a free preview video which is used as promotion for the original video.
///
- public VideoId PreviewVideoId { get; }
-
- ///
- /// Initializes an instance of
- ///
- public VideoRequiresPurchaseException(string message, VideoId previewVideoId)
- : base(message) => PreviewVideoId = previewVideoId;
+ public VideoId PreviewVideoId { get; } = previewVideoId;
}
diff --git a/YoutubeExplode/Exceptions/VideoUnavailableException.cs b/YoutubeExplode/Exceptions/VideoUnavailableException.cs
index af7f0e1a..1727757e 100644
--- a/YoutubeExplode/Exceptions/VideoUnavailableException.cs
+++ b/YoutubeExplode/Exceptions/VideoUnavailableException.cs
@@ -3,11 +3,4 @@ namespace YoutubeExplode.Exceptions;
///
/// Exception thrown when the requested video is unavailable.
///
-public class VideoUnavailableException : VideoUnplayableException
-{
- ///
- /// Initializes an instance of .
- ///
- public VideoUnavailableException(string message)
- : base(message) { }
-}
+public class VideoUnavailableException(string message) : VideoUnplayableException(message);
diff --git a/YoutubeExplode/Exceptions/VideoUnplayableException.cs b/YoutubeExplode/Exceptions/VideoUnplayableException.cs
index c7c65f7f..3964c781 100644
--- a/YoutubeExplode/Exceptions/VideoUnplayableException.cs
+++ b/YoutubeExplode/Exceptions/VideoUnplayableException.cs
@@ -3,11 +3,4 @@ namespace YoutubeExplode.Exceptions;
///
/// Exception thrown when the requested video is unplayable.
///
-public class VideoUnplayableException : YoutubeExplodeException
-{
- ///
- /// Initializes an instance of .
- ///
- public VideoUnplayableException(string message)
- : base(message) { }
-}
+public class VideoUnplayableException(string message) : YoutubeExplodeException(message);
diff --git a/YoutubeExplode/Exceptions/YoutubeExplodeException.cs b/YoutubeExplode/Exceptions/YoutubeExplodeException.cs
index e8385d66..91875d45 100644
--- a/YoutubeExplode/Exceptions/YoutubeExplodeException.cs
+++ b/YoutubeExplode/Exceptions/YoutubeExplodeException.cs
@@ -5,12 +5,4 @@ namespace YoutubeExplode.Exceptions;
///
/// Exception thrown within .
///
-public class YoutubeExplodeException : Exception
-{
- ///
- /// Initializes an instance of .
- ///
- ///
- public YoutubeExplodeException(string message)
- : base(message) { }
-}
+public class YoutubeExplodeException(string message) : Exception(message);
diff --git a/YoutubeExplode/Playlists/Playlist.cs b/YoutubeExplode/Playlists/Playlist.cs
index 141c9dec..37a770fd 100644
--- a/YoutubeExplode/Playlists/Playlist.cs
+++ b/YoutubeExplode/Playlists/Playlist.cs
@@ -7,45 +7,33 @@ namespace YoutubeExplode.Playlists;
///
/// Metadata associated with a YouTube playlist.
///
-public class Playlist : IPlaylist
+public class Playlist(
+ PlaylistId id,
+ string title,
+ Author? author,
+ string description,
+ IReadOnlyList thumbnails
+) : IPlaylist
{
///
- public PlaylistId Id { get; }
+ public PlaylistId Id { get; } = id;
///
public string Url => $"https://www.youtube.com/playlist?list={Id}";
///
- public string Title { get; }
+ public string Title { get; } = title;
///
- public Author? Author { get; }
+ public Author? Author { get; } = author;
///
/// Playlist description.
///
- public string Description { get; }
+ public string Description { get; } = description;
///
- public IReadOnlyList Thumbnails { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public Playlist(
- PlaylistId id,
- string title,
- Author? author,
- string description,
- IReadOnlyList thumbnails
- )
- {
- Id = id;
- Title = title;
- Author = author;
- Description = description;
- Thumbnails = thumbnails;
- }
+ public IReadOnlyList Thumbnails { get; } = thumbnails;
///
[ExcludeFromCodeCoverage]
diff --git a/YoutubeExplode/Playlists/PlaylistClient.cs b/YoutubeExplode/Playlists/PlaylistClient.cs
index 380fbd51..35d8dcdd 100644
--- a/YoutubeExplode/Playlists/PlaylistClient.cs
+++ b/YoutubeExplode/Playlists/PlaylistClient.cs
@@ -13,14 +13,9 @@ namespace YoutubeExplode.Playlists;
///
/// Operations related to YouTube playlists.
///
-public class PlaylistClient
+public class PlaylistClient(HttpClient http)
{
- private readonly PlaylistController _controller;
-
- ///
- /// Initializes an instance of .
- ///
- public PlaylistClient(HttpClient http) => _controller = new PlaylistController(http);
+ private readonly PlaylistController _controller = new(http);
///
/// Gets the metadata associated with the specified playlist.
diff --git a/YoutubeExplode/Playlists/PlaylistVideo.cs b/YoutubeExplode/Playlists/PlaylistVideo.cs
index 8b50a68e..227e6b3a 100644
--- a/YoutubeExplode/Playlists/PlaylistVideo.cs
+++ b/YoutubeExplode/Playlists/PlaylistVideo.cs
@@ -9,64 +9,51 @@ namespace YoutubeExplode.Playlists;
///
/// Metadata associated with a YouTube video included in a playlist.
///
-public class PlaylistVideo : IVideo, IBatchItem
+public class PlaylistVideo(
+ PlaylistId playlistId,
+ VideoId id,
+ string title,
+ Author author,
+ TimeSpan? duration,
+ IReadOnlyList thumbnails
+) : IVideo, IBatchItem
{
+ ///
+ /// Initializes an instance of .
+ ///
+ // Binary backwards compatibility (PlaylistId was added)
+ [Obsolete("Use the other constructor instead."), ExcludeFromCodeCoverage]
+ public PlaylistVideo(
+ VideoId id,
+ string title,
+ Author author,
+ TimeSpan? duration,
+ IReadOnlyList thumbnails
+ )
+ : this(default, id, title, author, duration, thumbnails) { }
+
///
/// ID of the playlist that contains this video.
///
- public PlaylistId PlaylistId { get; }
+ public PlaylistId PlaylistId { get; } = playlistId;
///
- public VideoId Id { get; }
+ public VideoId Id { get; } = id;
///
public string Url => $"https://www.youtube.com/watch?v={Id}&list={PlaylistId}";
///
- public string Title { get; }
+ public string Title { get; } = title;
///
- public Author Author { get; }
+ public Author Author { get; } = author;
///
- public TimeSpan? Duration { get; }
+ public TimeSpan? Duration { get; } = duration;
///
- public IReadOnlyList Thumbnails { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public PlaylistVideo(
- PlaylistId playlistId,
- VideoId id,
- string title,
- Author author,
- TimeSpan? duration,
- IReadOnlyList thumbnails
- )
- {
- PlaylistId = playlistId;
- Id = id;
- Title = title;
- Author = author;
- Duration = duration;
- Thumbnails = thumbnails;
- }
-
- ///
- /// Initializes an instance of .
- ///
- // Binary backwards compatibility (PlaylistId was added)
- [Obsolete("Use the other constructor instead."), ExcludeFromCodeCoverage]
- public PlaylistVideo(
- VideoId id,
- string title,
- Author author,
- TimeSpan? duration,
- IReadOnlyList thumbnails
- )
- : this(default, id, title, author, duration, thumbnails) { }
+ public IReadOnlyList Thumbnails { get; } = thumbnails;
///
[ExcludeFromCodeCoverage]
diff --git a/YoutubeExplode/Search/ChannelSearchResult.cs b/YoutubeExplode/Search/ChannelSearchResult.cs
index 8bdaf94b..7fc832b6 100644
--- a/YoutubeExplode/Search/ChannelSearchResult.cs
+++ b/YoutubeExplode/Search/ChannelSearchResult.cs
@@ -8,29 +8,21 @@ namespace YoutubeExplode.Search;
///
/// Metadata associated with a YouTube channel returned by a search query.
///
-public class ChannelSearchResult : ISearchResult, IChannel
+public class ChannelSearchResult(ChannelId id, string title, IReadOnlyList thumbnails)
+ : ISearchResult,
+ IChannel
{
///
- public ChannelId Id { get; }
+ public ChannelId Id { get; } = id;
///
public string Url => $"https://www.youtube.com/channel/{Id}";
///
- public string Title { get; }
+ public string Title { get; } = title;
///
- public IReadOnlyList Thumbnails { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public ChannelSearchResult(ChannelId id, string title, IReadOnlyList thumbnails)
- {
- Id = id;
- Title = title;
- Thumbnails = thumbnails;
- }
+ public IReadOnlyList Thumbnails { get; } = thumbnails;
///
[ExcludeFromCodeCoverage]
diff --git a/YoutubeExplode/Search/PlaylistSearchResult.cs b/YoutubeExplode/Search/PlaylistSearchResult.cs
index 49127f0e..eda25e5e 100644
--- a/YoutubeExplode/Search/PlaylistSearchResult.cs
+++ b/YoutubeExplode/Search/PlaylistSearchResult.cs
@@ -8,38 +8,27 @@ namespace YoutubeExplode.Search;
///
/// Metadata associated with a YouTube playlist returned by a search query.
///
-public class PlaylistSearchResult : ISearchResult, IPlaylist
+public class PlaylistSearchResult(
+ PlaylistId id,
+ string title,
+ Author? author,
+ IReadOnlyList thumbnails
+) : ISearchResult, IPlaylist
{
///
- public PlaylistId Id { get; }
+ public PlaylistId Id { get; } = id;
///
public string Url => $"https://www.youtube.com/playlist?list={Id}";
///
- public string Title { get; }
+ public string Title { get; } = title;
///
- public Author? Author { get; }
+ public Author? Author { get; } = author;
///
- public IReadOnlyList Thumbnails { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public PlaylistSearchResult(
- PlaylistId id,
- string title,
- Author? author,
- IReadOnlyList thumbnails
- )
- {
- Id = id;
- Title = title;
- Author = author;
- Thumbnails = thumbnails;
- }
+ public IReadOnlyList Thumbnails { get; } = thumbnails;
///
[ExcludeFromCodeCoverage]
diff --git a/YoutubeExplode/Search/SearchClient.cs b/YoutubeExplode/Search/SearchClient.cs
index 8a00433e..521631c5 100644
--- a/YoutubeExplode/Search/SearchClient.cs
+++ b/YoutubeExplode/Search/SearchClient.cs
@@ -14,14 +14,9 @@ namespace YoutubeExplode.Search;
///
/// Operations related to YouTube search.
///
-public class SearchClient
+public class SearchClient(HttpClient http)
{
- private readonly SearchController _controller;
-
- ///
- /// Initializes an instance of .
- ///
- public SearchClient(HttpClient http) => _controller = new SearchController(http);
+ private readonly SearchController _controller = new(http);
///
/// Enumerates batches of search results returned by the specified query.
diff --git a/YoutubeExplode/Search/VideoSearchResult.cs b/YoutubeExplode/Search/VideoSearchResult.cs
index dd847578..df158bab 100644
--- a/YoutubeExplode/Search/VideoSearchResult.cs
+++ b/YoutubeExplode/Search/VideoSearchResult.cs
@@ -9,43 +9,31 @@ namespace YoutubeExplode.Search;
///
/// Metadata associated with a YouTube video returned by a search query.
///
-public class VideoSearchResult : ISearchResult, IVideo
+public class VideoSearchResult(
+ VideoId id,
+ string title,
+ Author author,
+ TimeSpan? duration,
+ IReadOnlyList thumbnails
+) : ISearchResult, IVideo
{
///
- public VideoId Id { get; }
+ public VideoId Id { get; } = id;
///
public string Url => $"https://www.youtube.com/watch?v={Id}";
///
- public string Title { get; }
+ public string Title { get; } = title;
///
- public Author Author { get; }
+ public Author Author { get; } = author;
///
- public TimeSpan? Duration { get; }
+ public TimeSpan? Duration { get; } = duration;
///
- public IReadOnlyList Thumbnails { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public VideoSearchResult(
- VideoId id,
- string title,
- Author author,
- TimeSpan? duration,
- IReadOnlyList thumbnails
- )
- {
- Id = id;
- Title = title;
- Author = author;
- Duration = duration;
- Thumbnails = thumbnails;
- }
+ public IReadOnlyList Thumbnails { get; } = thumbnails;
///
[ExcludeFromCodeCoverage]
diff --git a/YoutubeExplode/Videos/ClosedCaptions/ClosedCaption.cs b/YoutubeExplode/Videos/ClosedCaptions/ClosedCaption.cs
index 1b3f8a3e..fe993604 100644
--- a/YoutubeExplode/Videos/ClosedCaptions/ClosedCaption.cs
+++ b/YoutubeExplode/Videos/ClosedCaptions/ClosedCaption.cs
@@ -8,22 +8,27 @@ namespace YoutubeExplode.Videos.ClosedCaptions;
///
/// Individual closed caption contained within a track.
///
-public class ClosedCaption
+public class ClosedCaption(
+ string text,
+ TimeSpan offset,
+ TimeSpan duration,
+ IReadOnlyList parts
+)
{
///
/// Text displayed by the caption.
///
- public string Text { get; }
+ public string Text { get; } = text;
///
/// Time at which the caption starts displaying.
///
- public TimeSpan Offset { get; }
+ public TimeSpan Offset { get; } = offset;
///
/// Duration of time for which the caption is displayed.
///
- public TimeSpan Duration { get; }
+ public TimeSpan Duration { get; } = duration;
///
/// Caption parts, usually representing individual words.
@@ -31,23 +36,7 @@ public class ClosedCaption
///
/// May be empty because not all captions have parts.
///
- public IReadOnlyList Parts { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public ClosedCaption(
- string text,
- TimeSpan offset,
- TimeSpan duration,
- IReadOnlyList parts
- )
- {
- Text = text;
- Offset = offset;
- Duration = duration;
- Parts = parts;
- }
+ public IReadOnlyList Parts { get; } = parts;
///
/// Gets the caption part displayed at the specified point in time, relative to the caption's own offset.
diff --git a/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionClient.cs b/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionClient.cs
index bb5e32e6..d267144d 100644
--- a/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionClient.cs
+++ b/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionClient.cs
@@ -15,14 +15,9 @@ namespace YoutubeExplode.Videos.ClosedCaptions;
///
/// Operations related to closed captions of YouTube videos.
///
-public class ClosedCaptionClient
+public class ClosedCaptionClient(HttpClient http)
{
- private readonly ClosedCaptionController _controller;
-
- ///
- /// Initializes an instance of .
- ///
- public ClosedCaptionClient(HttpClient http) => _controller = new ClosedCaptionController(http);
+ private readonly ClosedCaptionController _controller = new(http);
private async IAsyncEnumerable GetClosedCaptionTrackInfosAsync(
VideoId videoId,
diff --git a/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionManifest.cs b/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionManifest.cs
index cd9f3521..1e2ed660 100644
--- a/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionManifest.cs
+++ b/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionManifest.cs
@@ -7,17 +7,12 @@ namespace YoutubeExplode.Videos.ClosedCaptions;
///
/// Describes closed caption tracks available for a YouTube video.
///
-public class ClosedCaptionManifest
+public class ClosedCaptionManifest(IReadOnlyList tracks)
{
///
/// Available closed caption tracks.
///
- public IReadOnlyList Tracks { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public ClosedCaptionManifest(IReadOnlyList tracks) => Tracks = tracks;
+ public IReadOnlyList Tracks { get; } = tracks;
///
/// Gets the closed caption track in the specified language (identified by ISO-639-1 code or display name).
diff --git a/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionPart.cs b/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionPart.cs
index 31091e98..6e54c92d 100644
--- a/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionPart.cs
+++ b/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionPart.cs
@@ -1,31 +1,23 @@
using System;
using System.Diagnostics.CodeAnalysis;
+using AngleSharp.Media.Dom;
namespace YoutubeExplode.Videos.ClosedCaptions;
///
/// Individual closed caption part contained within a track.
///
-public class ClosedCaptionPart
+public class ClosedCaptionPart(string text, TimeSpan offset)
{
///
/// Text displayed by the caption part.
///
- public string Text { get; }
+ public string Text { get; } = text;
///
/// Time at which the caption part starts displaying, relative to the caption's own offset.
///
- public TimeSpan Offset { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public ClosedCaptionPart(string text, TimeSpan offset)
- {
- Text = text;
- Offset = offset;
- }
+ public TimeSpan Offset { get; } = offset;
///
[ExcludeFromCodeCoverage]
diff --git a/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionTrack.cs b/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionTrack.cs
index 28319502..57966cd9 100644
--- a/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionTrack.cs
+++ b/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionTrack.cs
@@ -7,20 +7,12 @@ namespace YoutubeExplode.Videos.ClosedCaptions;
///
/// Contains closed captions in a specific language.
///
-public class ClosedCaptionTrack
+public class ClosedCaptionTrack(IReadOnlyList captions)
{
///
/// Closed captions included in the track.
///
- public IReadOnlyList Captions { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public ClosedCaptionTrack(IReadOnlyList captions)
- {
- Captions = captions;
- }
+ public IReadOnlyList Captions { get; } = captions;
///
/// Gets the caption displayed at the specified point in time.
diff --git a/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionTrackInfo.cs b/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionTrackInfo.cs
index 7802365a..c7120400 100644
--- a/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionTrackInfo.cs
+++ b/YoutubeExplode/Videos/ClosedCaptions/ClosedCaptionTrackInfo.cs
@@ -5,32 +5,22 @@ namespace YoutubeExplode.Videos.ClosedCaptions;
///
/// Metadata associated with a closed caption track of a YouTube video.
///
-public class ClosedCaptionTrackInfo
+public class ClosedCaptionTrackInfo(string url, Language language, bool isAutoGenerated)
{
///
/// Track URL.
///
- public string Url { get; }
+ public string Url { get; } = url;
///
/// Track language.
///
- public Language Language { get; }
+ public Language Language { get; } = language;
///
/// Whether the track was automatically generated.
///
- public bool IsAutoGenerated { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public ClosedCaptionTrackInfo(string url, Language language, bool isAutoGenerated)
- {
- Url = url;
- Language = language;
- IsAutoGenerated = isAutoGenerated;
- }
+ public bool IsAutoGenerated { get; } = isAutoGenerated;
///
[ExcludeFromCodeCoverage]
diff --git a/YoutubeExplode/Videos/ClosedCaptions/Language.cs b/YoutubeExplode/Videos/ClosedCaptions/Language.cs
index 7f05b4cc..4d25af38 100644
--- a/YoutubeExplode/Videos/ClosedCaptions/Language.cs
+++ b/YoutubeExplode/Videos/ClosedCaptions/Language.cs
@@ -6,27 +6,18 @@ namespace YoutubeExplode.Videos.ClosedCaptions;
///
/// Language information.
///
-public readonly partial struct Language
+public readonly partial struct Language(string code, string name)
{
///
/// Two-letter or three-letter language code, possibly with a regional identifier
/// (e.g. 'en' or 'en-US' or 'eng').
///
- public string Code { get; }
+ public string Code { get; } = code;
///
/// Full international name of the language.
///
- public string Name { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public Language(string code, string name)
- {
- Code = code;
- Name = name;
- }
+ public string Name { get; } = name;
///
[ExcludeFromCodeCoverage]
diff --git a/YoutubeExplode/Videos/Engagement.cs b/YoutubeExplode/Videos/Engagement.cs
index 75b89446..08da2a1c 100644
--- a/YoutubeExplode/Videos/Engagement.cs
+++ b/YoutubeExplode/Videos/Engagement.cs
@@ -5,17 +5,17 @@ namespace YoutubeExplode.Videos;
///
/// Engagement statistics.
///
-public class Engagement
+public class Engagement(long viewCount, long likeCount, long dislikeCount)
{
///
/// View count.
///
- public long ViewCount { get; }
+ public long ViewCount { get; } = viewCount;
///
/// Like count.
///
- public long LikeCount { get; }
+ public long LikeCount { get; } = likeCount;
///
/// Dislike count.
@@ -23,7 +23,7 @@ public class Engagement
///
/// YouTube no longer shows dislikes, so this value is always 0.
///
- public long DislikeCount { get; }
+ public long DislikeCount { get; } = dislikeCount;
///
/// Average rating.
@@ -34,16 +34,6 @@ public class Engagement
public double AverageRating =>
LikeCount + DislikeCount != 0 ? 1 + 4.0 * LikeCount / (LikeCount + DislikeCount) : 0; // avoid division by 0
- ///
- /// Initializes an instance of .
- ///
- public Engagement(long viewCount, long likeCount, long dislikeCount)
- {
- ViewCount = viewCount;
- LikeCount = likeCount;
- DislikeCount = dislikeCount;
- }
-
///
[ExcludeFromCodeCoverage]
public override string ToString() => $"Rating: {AverageRating:N1}";
diff --git a/YoutubeExplode/Videos/Streams/AudioOnlyStreamInfo.cs b/YoutubeExplode/Videos/Streams/AudioOnlyStreamInfo.cs
index 1346d2a1..59cb8e55 100644
--- a/YoutubeExplode/Videos/Streams/AudioOnlyStreamInfo.cs
+++ b/YoutubeExplode/Videos/Streams/AudioOnlyStreamInfo.cs
@@ -5,40 +5,28 @@ namespace YoutubeExplode.Videos.Streams;
///
/// Metadata associated with an audio-only YouTube media stream.
///
-public class AudioOnlyStreamInfo : IAudioStreamInfo
+public class AudioOnlyStreamInfo(
+ string url,
+ Container container,
+ FileSize size,
+ Bitrate bitrate,
+ string audioCodec
+) : IAudioStreamInfo
{
///
- public string Url { get; }
+ public string Url { get; } = url;
///
- public Container Container { get; }
+ public Container Container { get; } = container;
///
- public FileSize Size { get; }
+ public FileSize Size { get; } = size;
///
- public Bitrate Bitrate { get; }
+ public Bitrate Bitrate { get; } = bitrate;
///
- public string AudioCodec { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public AudioOnlyStreamInfo(
- string url,
- Container container,
- FileSize size,
- Bitrate bitrate,
- string audioCodec
- )
- {
- Url = url;
- Container = container;
- Size = size;
- Bitrate = bitrate;
- AudioCodec = audioCodec;
- }
+ public string AudioCodec { get; } = audioCodec;
///
[ExcludeFromCodeCoverage]
diff --git a/YoutubeExplode/Videos/Streams/Bitrate.cs b/YoutubeExplode/Videos/Streams/Bitrate.cs
index 50f6a6f7..54d2fc0b 100644
--- a/YoutubeExplode/Videos/Streams/Bitrate.cs
+++ b/YoutubeExplode/Videos/Streams/Bitrate.cs
@@ -5,12 +5,12 @@ namespace YoutubeExplode.Videos.Streams;
///
/// Bitrate.
///
-public readonly partial struct Bitrate
+public readonly partial struct Bitrate(long bitsPerSecond)
{
///
/// Bitrate in bits per second.
///
- public long BitsPerSecond { get; }
+ public long BitsPerSecond { get; } = bitsPerSecond;
///
/// Bitrate in kilobits per second.
@@ -27,11 +27,6 @@ public readonly partial struct Bitrate
///
public double GigaBitsPerSecond => MegaBitsPerSecond / 1024.0;
- ///
- /// Initializes an instance of .
- ///
- public Bitrate(long bitsPerSecond) => BitsPerSecond = bitsPerSecond;
-
private string GetLargestWholeNumberSymbol()
{
if (Math.Abs(GigaBitsPerSecond) >= 1)
diff --git a/YoutubeExplode/Videos/Streams/Container.cs b/YoutubeExplode/Videos/Streams/Container.cs
index 52a8e02a..10cef6fe 100644
--- a/YoutubeExplode/Videos/Streams/Container.cs
+++ b/YoutubeExplode/Videos/Streams/Container.cs
@@ -5,13 +5,13 @@ namespace YoutubeExplode.Videos.Streams;
///
/// Stream container.
///
-public readonly partial struct Container
+public readonly partial struct Container(string name)
{
///
/// Container name (e.g. mp4, webm, etc).
/// Can be used as file extension.
///
- public string Name { get; }
+ public string Name { get; } = name;
///
/// Whether this container is a known audio-only container.
@@ -30,11 +30,6 @@ public readonly partial struct Container
|| string.Equals(Name, "aac", StringComparison.OrdinalIgnoreCase)
|| string.Equals(Name, "opus", StringComparison.OrdinalIgnoreCase);
- ///
- /// Initializes an instance of .
- ///
- public Container(string name) => Name = name;
-
///
public override string ToString() => Name;
}
diff --git a/YoutubeExplode/Videos/Streams/FileSize.cs b/YoutubeExplode/Videos/Streams/FileSize.cs
index d0086284..7d236529 100644
--- a/YoutubeExplode/Videos/Streams/FileSize.cs
+++ b/YoutubeExplode/Videos/Streams/FileSize.cs
@@ -6,12 +6,12 @@ namespace YoutubeExplode.Videos.Streams;
/// File size.
///
// Loosely based on https://github.com/omar/ByteSize (MIT license)
-public readonly partial struct FileSize
+public readonly partial struct FileSize(long bytes)
{
///
/// Size in bytes.
///
- public long Bytes { get; }
+ public long Bytes { get; } = bytes;
///
/// Size in kilobytes.
@@ -28,11 +28,6 @@ public readonly partial struct FileSize
///
public double GigaBytes => MegaBytes / 1024.0;
- ///
- /// Initializes an instance of .
- ///
- public FileSize(long bytes) => Bytes = bytes;
-
private string GetLargestWholeNumberSymbol()
{
if (Math.Abs(GigaBytes) >= 1)
diff --git a/YoutubeExplode/Videos/Streams/MuxedStreamInfo.cs b/YoutubeExplode/Videos/Streams/MuxedStreamInfo.cs
index a07358c0..0983038b 100644
--- a/YoutubeExplode/Videos/Streams/MuxedStreamInfo.cs
+++ b/YoutubeExplode/Videos/Streams/MuxedStreamInfo.cs
@@ -6,55 +6,40 @@ namespace YoutubeExplode.Videos.Streams;
///
/// Metadata associated with a muxed (audio + video combined) media stream.
///
-public class MuxedStreamInfo : IAudioStreamInfo, IVideoStreamInfo
+public class MuxedStreamInfo(
+ string url,
+ Container container,
+ FileSize size,
+ Bitrate bitrate,
+ string audioCodec,
+ string videoCodec,
+ VideoQuality videoQuality,
+ Resolution videoResolution
+) : IAudioStreamInfo, IVideoStreamInfo
{
///
- public string Url { get; }
+ public string Url { get; } = url;
///
- public Container Container { get; }
+ public Container Container { get; } = container;
///
- public FileSize Size { get; }
+ public FileSize Size { get; } = size;
///
- public Bitrate Bitrate { get; }
+ public Bitrate Bitrate { get; } = bitrate;
///
- public string AudioCodec { get; }
+ public string AudioCodec { get; } = audioCodec;
///
- public string VideoCodec { get; }
+ public string VideoCodec { get; } = videoCodec;
///
- public VideoQuality VideoQuality { get; }
+ public VideoQuality VideoQuality { get; } = videoQuality;
///
- public Resolution VideoResolution { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public MuxedStreamInfo(
- string url,
- Container container,
- FileSize size,
- Bitrate bitrate,
- string audioCodec,
- string videoCodec,
- VideoQuality videoQuality,
- Resolution resolution
- )
- {
- Url = url;
- Container = container;
- Size = size;
- Bitrate = bitrate;
- AudioCodec = audioCodec;
- VideoCodec = videoCodec;
- VideoQuality = videoQuality;
- VideoResolution = resolution;
- }
+ public Resolution VideoResolution { get; } = videoResolution;
///
[ExcludeFromCodeCoverage]
diff --git a/YoutubeExplode/Videos/Streams/StreamClient.cs b/YoutubeExplode/Videos/Streams/StreamClient.cs
index e27a7e76..d6db8c58 100644
--- a/YoutubeExplode/Videos/Streams/StreamClient.cs
+++ b/YoutubeExplode/Videos/Streams/StreamClient.cs
@@ -19,24 +19,14 @@ namespace YoutubeExplode.Videos.Streams;
///
/// Operations related to media streams of YouTube videos.
///
-public class StreamClient
+public class StreamClient(HttpClient http)
{
- private readonly HttpClient _http;
- private readonly StreamController _controller;
+ private readonly StreamController _controller = new(http);
// Because we determine the player version ourselves, it's safe to cache the cipher manifest
// for the entire lifetime of the client.
private CipherManifest? _cipherManifest;
- ///
- /// Initializes an instance of .
- ///
- public StreamClient(HttpClient http)
- {
- _http = http;
- _controller = new StreamController(http);
- }
-
private async ValueTask ResolveCipherManifestAsync(
CancellationToken cancellationToken
)
@@ -63,7 +53,7 @@ CancellationToken cancellationToken
// sending a HEAD request and parsing the Content-Length header.
if (contentLength is null)
{
- using var response = await _http.HeadAsync(url, cancellationToken);
+ using var response = await http.HeadAsync(url, cancellationToken);
contentLength = response.Content.Headers.ContentLength;
// 404 error indicates that the stream is not available
@@ -77,7 +67,7 @@ CancellationToken cancellationToken
{
// Streams may have mismatched content length, so ensure that the obtained value is correct
// https://github.com/Tyrrrz/YoutubeExplode/issues/759
- using var response = await _http.GetAsync(
+ using var response = await http.GetAsync(
// Try to access the last byte of the stream
MediaStream.GetSegmentUrl(url, contentLength.Value - 2, contentLength.Value - 1),
HttpCompletionOption.ResponseHeadersRead,
@@ -341,7 +331,7 @@ public async ValueTask GetAsync(
CancellationToken cancellationToken = default
)
{
- var stream = new MediaStream(_http, streamInfo);
+ var stream = new MediaStream(http, streamInfo);
await stream.InitializeAsync(cancellationToken);
return stream;
diff --git a/YoutubeExplode/Videos/Streams/StreamManifest.cs b/YoutubeExplode/Videos/Streams/StreamManifest.cs
index 7cb12d6e..d0a72f21 100644
--- a/YoutubeExplode/Videos/Streams/StreamManifest.cs
+++ b/YoutubeExplode/Videos/Streams/StreamManifest.cs
@@ -6,20 +6,12 @@ namespace YoutubeExplode.Videos.Streams;
///
/// Describes media streams available for a YouTube video.
///
-public class StreamManifest
+public class StreamManifest(IReadOnlyList streams)
{
///
/// Available streams.
///
- public IReadOnlyList Streams { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public StreamManifest(IReadOnlyList streams)
- {
- Streams = streams;
- }
+ public IReadOnlyList Streams { get; } = streams;
///
/// Gets streams that contain audio (i.e. muxed and audio-only streams).
diff --git a/YoutubeExplode/Videos/Streams/VideoOnlyStreamInfo.cs b/YoutubeExplode/Videos/Streams/VideoOnlyStreamInfo.cs
index 487d793b..b96a43f7 100644
--- a/YoutubeExplode/Videos/Streams/VideoOnlyStreamInfo.cs
+++ b/YoutubeExplode/Videos/Streams/VideoOnlyStreamInfo.cs
@@ -6,50 +6,36 @@ namespace YoutubeExplode.Videos.Streams;
///
/// Metadata associated with a video-only media stream.
///
-public class VideoOnlyStreamInfo : IVideoStreamInfo
+public class VideoOnlyStreamInfo(
+ string url,
+ Container container,
+ FileSize size,
+ Bitrate bitrate,
+ string videoCodec,
+ VideoQuality videoQuality,
+ Resolution videoResolution
+) : IVideoStreamInfo
{
///
- public string Url { get; }
+ public string Url { get; } = url;
///
- public Container Container { get; }
+ public Container Container { get; } = container;
///
- public FileSize Size { get; }
+ public FileSize Size { get; } = size;
///
- public Bitrate Bitrate { get; }
+ public Bitrate Bitrate { get; } = bitrate;
///
- public string VideoCodec { get; }
+ public string VideoCodec { get; } = videoCodec;
///
- public VideoQuality VideoQuality { get; }
+ public VideoQuality VideoQuality { get; } = videoQuality;
///
- public Resolution VideoResolution { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public VideoOnlyStreamInfo(
- string url,
- Container container,
- FileSize size,
- Bitrate bitrate,
- string videoCodec,
- VideoQuality videoQuality,
- Resolution videoResolution
- )
- {
- Url = url;
- Container = container;
- Size = size;
- Bitrate = bitrate;
- VideoCodec = videoCodec;
- VideoQuality = videoQuality;
- VideoResolution = videoResolution;
- }
+ public Resolution VideoResolution { get; } = videoResolution;
///
[ExcludeFromCodeCoverage]
diff --git a/YoutubeExplode/Videos/Streams/VideoQuality.cs b/YoutubeExplode/Videos/Streams/VideoQuality.cs
index fcf3bbd4..f52b875d 100644
--- a/YoutubeExplode/Videos/Streams/VideoQuality.cs
+++ b/YoutubeExplode/Videos/Streams/VideoQuality.cs
@@ -8,45 +8,35 @@ namespace YoutubeExplode.Videos.Streams;
///
/// Video stream quality.
///
-public readonly partial struct VideoQuality
+public readonly partial struct VideoQuality(string label, int maxHeight, int framerate)
{
+ ///
+ /// Initializes an instance of .
+ ///
+ public VideoQuality(int maxHeight, int framerate)
+ : this(FormatLabel(maxHeight, framerate), maxHeight, framerate) { }
+
///
/// Quality label, as seen on YouTube (e.g. 1080p, 720p60, etc).
///
- public string Label { get; }
+ public string Label { get; } = label;
///
/// Maximum video height allowed by this quality (e.g. 1080 for 1080p60).
/// Actual video height may be lower in some cases.
///
- public int MaxHeight { get; }
+ public int MaxHeight { get; } = maxHeight;
///
/// Video framerate, measured in frames per second.
///
- public int Framerate { get; }
+ public int Framerate { get; } = framerate;
///
/// Whether this is a high definition video (i.e. 1080p or above).
///
public bool IsHighDefinition => MaxHeight >= 1080;
- ///
- /// Initializes an instance of .
- ///
- public VideoQuality(string label, int maxHeight, int framerate)
- {
- Label = label;
- MaxHeight = maxHeight;
- Framerate = framerate;
- }
-
- ///
- /// Initializes an instance of .
- ///
- public VideoQuality(int maxHeight, int framerate)
- : this(FormatLabel(maxHeight, framerate), maxHeight, framerate) { }
-
internal Resolution GetDefaultVideoResolution() =>
MaxHeight switch
{
diff --git a/YoutubeExplode/Videos/Video.cs b/YoutubeExplode/Videos/Video.cs
index b2661f31..04734623 100644
--- a/YoutubeExplode/Videos/Video.cs
+++ b/YoutubeExplode/Videos/Video.cs
@@ -8,71 +8,55 @@ namespace YoutubeExplode.Videos;
///
/// Metadata associated with a YouTube video.
///
-public class Video : IVideo
+public class Video(
+ VideoId id,
+ string title,
+ Author author,
+ DateTimeOffset uploadDate,
+ string description,
+ TimeSpan? duration,
+ IReadOnlyList thumbnails,
+ IReadOnlyList keywords,
+ Engagement engagement
+) : IVideo
{
///
- public VideoId Id { get; }
+ public VideoId Id { get; } = id;
///
public string Url => $"https://www.youtube.com/watch?v={Id}";
///
- public string Title { get; }
+ public string Title { get; } = title;
///
- public Author Author { get; }
+ public Author Author { get; } = author;
///
/// Video upload date.
///
- public DateTimeOffset UploadDate { get; }
+ public DateTimeOffset UploadDate { get; } = uploadDate;
///
/// Video description.
///
- public string Description { get; }
+ public string Description { get; } = description;
///
- public TimeSpan? Duration { get; }
+ public TimeSpan? Duration { get; } = duration;
///
- public IReadOnlyList Thumbnails { get; }
+ public IReadOnlyList Thumbnails { get; } = thumbnails;
///
/// Available search keywords for the video.
///
- public IReadOnlyList Keywords { get; }
+ public IReadOnlyList Keywords { get; } = keywords;
///
/// Engagement statistics for the video.
///
- public Engagement Engagement { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public Video(
- VideoId id,
- string title,
- Author author,
- DateTimeOffset uploadDate,
- string description,
- TimeSpan? duration,
- IReadOnlyList thumbnails,
- IReadOnlyList keywords,
- Engagement engagement
- )
- {
- Id = id;
- Title = title;
- Author = author;
- UploadDate = uploadDate;
- Description = description;
- Duration = duration;
- Thumbnails = thumbnails;
- Keywords = keywords;
- Engagement = engagement;
- }
+ public Engagement Engagement { get; } = engagement;
///
[ExcludeFromCodeCoverage]
diff --git a/YoutubeExplode/Videos/VideoClient.cs b/YoutubeExplode/Videos/VideoClient.cs
index 46e9059e..b4063101 100644
--- a/YoutubeExplode/Videos/VideoClient.cs
+++ b/YoutubeExplode/Videos/VideoClient.cs
@@ -12,30 +12,19 @@ namespace YoutubeExplode.Videos;
///
/// Operations related to YouTube videos.
///
-public class VideoClient
+public class VideoClient(HttpClient http)
{
- private readonly VideoController _controller;
+ private readonly VideoController _controller = new(http);
///
/// Operations related to media streams of YouTube videos.
///
- public StreamClient Streams { get; }
+ public StreamClient Streams { get; } = new(http);
///
/// Operations related to closed captions of YouTube videos.
///
- public ClosedCaptionClient ClosedCaptions { get; }
-
- ///
- /// Initializes an instance of .
- ///
- public VideoClient(HttpClient http)
- {
- _controller = new VideoController(http);
-
- Streams = new StreamClient(http);
- ClosedCaptions = new ClosedCaptionClient(http);
- }
+ public ClosedCaptionClient ClosedCaptions { get; } = new(http);
///
/// Gets the metadata associated with the specified video.