< Summary - Jellyfin

Information
Class: Jellyfin.Api.Controllers.AudioController
Assembly: Jellyfin.Api
File(s): /srv/git/jellyfin/Jellyfin.Api/Controllers/AudioController.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 3
Coverable lines: 3
Total lines: 361
Line coverage: 0%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Coverage history

Coverage history 0 25 50 75 100 10/18/2025 - 12:10:13 AM Line coverage: 0% (0/3) Total lines: 3671/19/2026 - 12:13:54 AM Line coverage: 0% (0/3) Total lines: 361

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%

File(s)

/srv/git/jellyfin/Jellyfin.Api/Controllers/AudioController.cs

#LineLine coverage
 1using System;
 2using System.Collections.Generic;
 3using System.ComponentModel.DataAnnotations;
 4using System.Threading.Tasks;
 5using Jellyfin.Api.Attributes;
 6using Jellyfin.Api.Helpers;
 7using Jellyfin.Api.Models.StreamingDtos;
 8using MediaBrowser.Controller.MediaEncoding;
 9using MediaBrowser.Controller.Streaming;
 10using MediaBrowser.Model.Dlna;
 11using Microsoft.AspNetCore.Http;
 12using Microsoft.AspNetCore.Mvc;
 13
 14namespace Jellyfin.Api.Controllers;
 15
 16/// <summary>
 17/// The audio controller.
 18/// </summary>
 19public class AudioController : BaseJellyfinApiController
 20{
 21    private readonly AudioHelper _audioHelper;
 22
 23    private readonly TranscodingJobType _transcodingJobType = TranscodingJobType.Progressive;
 24
 25    /// <summary>
 26    /// Initializes a new instance of the <see cref="AudioController"/> class.
 27    /// </summary>
 28    /// <param name="audioHelper">Instance of <see cref="AudioHelper"/>.</param>
 029    public AudioController(AudioHelper audioHelper)
 30    {
 031        _audioHelper = audioHelper;
 032    }
 33
 34    /// <summary>
 35    /// Gets an audio stream.
 36    /// </summary>
 37    /// <param name="itemId">The item id.</param>
 38    /// <param name="container">The audio container.</param>
 39    /// <param name="static">Optional. If true, the original file will be streamed statically without any encoding. Use 
 40    /// <param name="params">The streaming parameters.</param>
 41    /// <param name="tag">The tag.</param>
 42    /// <param name="deviceProfileId">Optional. The dlna device profile id to utilize.</param>
 43    /// <param name="playSessionId">The play session id.</param>
 44    /// <param name="segmentContainer">The segment container.</param>
 45    /// <param name="segmentLength">The segment length.</param>
 46    /// <param name="minSegments">The minimum number of segments.</param>
 47    /// <param name="mediaSourceId">The media version id, if playing an alternate version.</param>
 48    /// <param name="deviceId">The device id of the client requesting. Used to stop encoding processes when needed.</par
 49    /// <param name="audioCodec">Optional. Specify an audio codec to encode to, e.g. mp3. If omitted the server will aut
 50    /// <param name="enableAutoStreamCopy">Whether or not to allow automatic stream copy if requested values match the o
 51    /// <param name="allowVideoStreamCopy">Whether or not to allow copying of the video stream url.</param>
 52    /// <param name="allowAudioStreamCopy">Whether or not to allow copying of the audio stream url.</param>
 53    /// <param name="audioSampleRate">Optional. Specify a specific audio sample rate, e.g. 44100.</param>
 54    /// <param name="maxAudioBitDepth">Optional. The maximum audio bit depth.</param>
 55    /// <param name="audioBitRate">Optional. Specify an audio bitrate to encode to, e.g. 128000. If omitted this will be
 56    /// <param name="audioChannels">Optional. Specify a specific number of audio channels to encode to, e.g. 2.</param>
 57    /// <param name="maxAudioChannels">Optional. Specify a maximum number of audio channels to encode to, e.g. 2.</param
 58    /// <param name="profile">Optional. Specify a specific an encoder profile (varies by encoder), e.g. main, baseline, 
 59    /// <param name="level">Optional. Specify a level for the encoder profile (varies by encoder), e.g. 3, 3.1.</param>
 60    /// <param name="framerate">Optional. A specific video framerate to encode to, e.g. 23.976. Generally this should be
 61    /// <param name="maxFramerate">Optional. A specific maximum video framerate to encode to, e.g. 23.976. Generally thi
 62    /// <param name="copyTimestamps">Whether or not to copy timestamps when transcoding with an offset. Defaults to fals
 63    /// <param name="startTimeTicks">Optional. Specify a starting offset, in ticks. 1 tick = 10000 ms.</param>
 64    /// <param name="width">Optional. The fixed horizontal resolution of the encoded video.</param>
 65    /// <param name="height">Optional. The fixed vertical resolution of the encoded video.</param>
 66    /// <param name="videoBitRate">Optional. Specify a video bitrate to encode to, e.g. 500000. If omitted this will be 
 67    /// <param name="subtitleStreamIndex">Optional. The index of the subtitle stream to use. If omitted no subtitles wil
 68    /// <param name="subtitleMethod">Optional. Specify the subtitle delivery method.</param>
 69    /// <param name="maxRefFrames">Optional.</param>
 70    /// <param name="maxVideoBitDepth">Optional. The maximum video bit depth.</param>
 71    /// <param name="requireAvc">Optional. Whether to require avc.</param>
 72    /// <param name="deInterlace">Optional. Whether to deinterlace the video.</param>
 73    /// <param name="requireNonAnamorphic">Optional. Whether to require a non anamorphic stream.</param>
 74    /// <param name="transcodingMaxAudioChannels">Optional. The maximum number of audio channels to transcode.</param>
 75    /// <param name="cpuCoreLimit">Optional. The limit of how many cpu cores to use.</param>
 76    /// <param name="liveStreamId">The live stream id.</param>
 77    /// <param name="enableMpegtsM2TsMode">Optional. Whether to enable the MpegtsM2Ts mode.</param>
 78    /// <param name="videoCodec">Optional. Specify a video codec to encode to, e.g. h264. If omitted the server will aut
 79    /// <param name="subtitleCodec">Optional. Specify a subtitle codec to encode to.</param>
 80    /// <param name="transcodeReasons">Optional. The transcoding reason.</param>
 81    /// <param name="audioStreamIndex">Optional. The index of the audio stream to use. If omitted the first audio stream
 82    /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream
 83    /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param>
 84    /// <param name="streamOptions">Optional. The streaming options.</param>
 85    /// <param name="enableAudioVbrEncoding">Optional. Whether to enable Audio Encoding.</param>
 86    /// <response code="200">Audio stream returned.</response>
 87    /// <returns>A <see cref="FileResult"/> containing the audio file.</returns>
 88    [HttpGet("{itemId}/stream", Name = "GetAudioStream")]
 89    [HttpHead("{itemId}/stream", Name = "HeadAudioStream")]
 90    [ProducesResponseType(StatusCodes.Status200OK)]
 91    [ProducesAudioFile]
 92    public async Task<ActionResult> GetAudioStream(
 93        [FromRoute, Required] Guid itemId,
 94        [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? container,
 95        [FromQuery] bool? @static,
 96        [FromQuery] string? @params,
 97        [FromQuery] string? tag,
 98        [FromQuery, ParameterObsolete] string? deviceProfileId,
 99        [FromQuery] string? playSessionId,
 100        [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer,
 101        [FromQuery] int? segmentLength,
 102        [FromQuery] int? minSegments,
 103        [FromQuery] string? mediaSourceId,
 104        [FromQuery] string? deviceId,
 105        [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec,
 106        [FromQuery] bool? enableAutoStreamCopy,
 107        [FromQuery] bool? allowVideoStreamCopy,
 108        [FromQuery] bool? allowAudioStreamCopy,
 109        [FromQuery] int? audioSampleRate,
 110        [FromQuery] int? maxAudioBitDepth,
 111        [FromQuery] int? audioBitRate,
 112        [FromQuery] int? audioChannels,
 113        [FromQuery] int? maxAudioChannels,
 114        [FromQuery] string? profile,
 115        [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level,
 116        [FromQuery] float? framerate,
 117        [FromQuery] float? maxFramerate,
 118        [FromQuery] bool? copyTimestamps,
 119        [FromQuery] long? startTimeTicks,
 120        [FromQuery] int? width,
 121        [FromQuery] int? height,
 122        [FromQuery] int? videoBitRate,
 123        [FromQuery] int? subtitleStreamIndex,
 124        [FromQuery] SubtitleDeliveryMethod? subtitleMethod,
 125        [FromQuery] int? maxRefFrames,
 126        [FromQuery] int? maxVideoBitDepth,
 127        [FromQuery] bool? requireAvc,
 128        [FromQuery] bool? deInterlace,
 129        [FromQuery] bool? requireNonAnamorphic,
 130        [FromQuery] int? transcodingMaxAudioChannels,
 131        [FromQuery] int? cpuCoreLimit,
 132        [FromQuery] string? liveStreamId,
 133        [FromQuery] bool? enableMpegtsM2TsMode,
 134        [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec,
 135        [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec,
 136        [FromQuery] string? transcodeReasons,
 137        [FromQuery] int? audioStreamIndex,
 138        [FromQuery] int? videoStreamIndex,
 139        [FromQuery] EncodingContext? context,
 140        [FromQuery] Dictionary<string, string>? streamOptions,
 141        [FromQuery] bool enableAudioVbrEncoding = true)
 142    {
 143        StreamingRequestDto streamingRequest = new StreamingRequestDto
 144        {
 145            Id = itemId,
 146            Container = container,
 147            Static = @static ?? false,
 148            Params = @params,
 149            Tag = tag,
 150            PlaySessionId = playSessionId,
 151            SegmentContainer = segmentContainer,
 152            SegmentLength = segmentLength,
 153            MinSegments = minSegments,
 154            MediaSourceId = mediaSourceId,
 155            DeviceId = deviceId,
 156            AudioCodec = audioCodec,
 157            EnableAutoStreamCopy = enableAutoStreamCopy ?? true,
 158            AllowAudioStreamCopy = allowAudioStreamCopy ?? true,
 159            AllowVideoStreamCopy = allowVideoStreamCopy ?? true,
 160            AudioSampleRate = audioSampleRate,
 161            MaxAudioChannels = maxAudioChannels,
 162            AudioBitRate = audioBitRate,
 163            MaxAudioBitDepth = maxAudioBitDepth,
 164            AudioChannels = audioChannels,
 165            Profile = profile,
 166            Level = level,
 167            Framerate = framerate,
 168            MaxFramerate = maxFramerate,
 169            CopyTimestamps = copyTimestamps ?? false,
 170            StartTimeTicks = startTimeTicks,
 171            Width = width,
 172            Height = height,
 173            VideoBitRate = videoBitRate,
 174            SubtitleStreamIndex = subtitleStreamIndex,
 175            SubtitleMethod = subtitleMethod ?? SubtitleDeliveryMethod.Encode,
 176            MaxRefFrames = maxRefFrames,
 177            MaxVideoBitDepth = maxVideoBitDepth,
 178            RequireAvc = requireAvc ?? false,
 179            DeInterlace = deInterlace ?? false,
 180            RequireNonAnamorphic = requireNonAnamorphic ?? false,
 181            TranscodingMaxAudioChannels = transcodingMaxAudioChannels,
 182            CpuCoreLimit = cpuCoreLimit,
 183            LiveStreamId = liveStreamId,
 184            EnableMpegtsM2TsMode = enableMpegtsM2TsMode ?? false,
 185            VideoCodec = videoCodec,
 186            SubtitleCodec = subtitleCodec,
 187            TranscodeReasons = transcodeReasons,
 188            AudioStreamIndex = audioStreamIndex,
 189            VideoStreamIndex = videoStreamIndex,
 190            Context = context ?? EncodingContext.Static,
 191            StreamOptions = streamOptions,
 192            EnableAudioVbrEncoding = enableAudioVbrEncoding
 193        };
 194
 195        return await _audioHelper.GetAudioStream(_transcodingJobType, streamingRequest).ConfigureAwait(false);
 196    }
 197
 198    /// <summary>
 199    /// Gets an audio stream.
 200    /// </summary>
 201    /// <param name="itemId">The item id.</param>
 202    /// <param name="container">The audio container.</param>
 203    /// <param name="static">Optional. If true, the original file will be streamed statically without any encoding. Use 
 204    /// <param name="params">The streaming parameters.</param>
 205    /// <param name="tag">The tag.</param>
 206    /// <param name="deviceProfileId">Optional. The dlna device profile id to utilize.</param>
 207    /// <param name="playSessionId">The play session id.</param>
 208    /// <param name="segmentContainer">The segment container.</param>
 209    /// <param name="segmentLength">The segment length.</param>
 210    /// <param name="minSegments">The minimum number of segments.</param>
 211    /// <param name="mediaSourceId">The media version id, if playing an alternate version.</param>
 212    /// <param name="deviceId">The device id of the client requesting. Used to stop encoding processes when needed.</par
 213    /// <param name="audioCodec">Optional. Specify an audio codec to encode to, e.g. mp3. If omitted the server will aut
 214    /// <param name="enableAutoStreamCopy">Whether or not to allow automatic stream copy if requested values match the o
 215    /// <param name="allowVideoStreamCopy">Whether or not to allow copying of the video stream url.</param>
 216    /// <param name="allowAudioStreamCopy">Whether or not to allow copying of the audio stream url.</param>
 217    /// <param name="audioSampleRate">Optional. Specify a specific audio sample rate, e.g. 44100.</param>
 218    /// <param name="maxAudioBitDepth">Optional. The maximum audio bit depth.</param>
 219    /// <param name="audioBitRate">Optional. Specify an audio bitrate to encode to, e.g. 128000. If omitted this will be
 220    /// <param name="audioChannels">Optional. Specify a specific number of audio channels to encode to, e.g. 2.</param>
 221    /// <param name="maxAudioChannels">Optional. Specify a maximum number of audio channels to encode to, e.g. 2.</param
 222    /// <param name="profile">Optional. Specify a specific an encoder profile (varies by encoder), e.g. main, baseline, 
 223    /// <param name="level">Optional. Specify a level for the encoder profile (varies by encoder), e.g. 3, 3.1.</param>
 224    /// <param name="framerate">Optional. A specific video framerate to encode to, e.g. 23.976. Generally this should be
 225    /// <param name="maxFramerate">Optional. A specific maximum video framerate to encode to, e.g. 23.976. Generally thi
 226    /// <param name="copyTimestamps">Whether or not to copy timestamps when transcoding with an offset. Defaults to fals
 227    /// <param name="startTimeTicks">Optional. Specify a starting offset, in ticks. 1 tick = 10000 ms.</param>
 228    /// <param name="width">Optional. The fixed horizontal resolution of the encoded video.</param>
 229    /// <param name="height">Optional. The fixed vertical resolution of the encoded video.</param>
 230    /// <param name="videoBitRate">Optional. Specify a video bitrate to encode to, e.g. 500000. If omitted this will be 
 231    /// <param name="subtitleStreamIndex">Optional. The index of the subtitle stream to use. If omitted no subtitles wil
 232    /// <param name="subtitleMethod">Optional. Specify the subtitle delivery method.</param>
 233    /// <param name="maxRefFrames">Optional.</param>
 234    /// <param name="maxVideoBitDepth">Optional. The maximum video bit depth.</param>
 235    /// <param name="requireAvc">Optional. Whether to require avc.</param>
 236    /// <param name="deInterlace">Optional. Whether to deinterlace the video.</param>
 237    /// <param name="requireNonAnamorphic">Optional. Whether to require a non anamorphic stream.</param>
 238    /// <param name="transcodingMaxAudioChannels">Optional. The maximum number of audio channels to transcode.</param>
 239    /// <param name="cpuCoreLimit">Optional. The limit of how many cpu cores to use.</param>
 240    /// <param name="liveStreamId">The live stream id.</param>
 241    /// <param name="enableMpegtsM2TsMode">Optional. Whether to enable the MpegtsM2Ts mode.</param>
 242    /// <param name="videoCodec">Optional. Specify a video codec to encode to, e.g. h264. If omitted the server will aut
 243    /// <param name="subtitleCodec">Optional. Specify a subtitle codec to encode to.</param>
 244    /// <param name="transcodeReasons">Optional. The transcoding reason.</param>
 245    /// <param name="audioStreamIndex">Optional. The index of the audio stream to use. If omitted the first audio stream
 246    /// <param name="videoStreamIndex">Optional. The index of the video stream to use. If omitted the first video stream
 247    /// <param name="context">Optional. The <see cref="EncodingContext"/>.</param>
 248    /// <param name="streamOptions">Optional. The streaming options.</param>
 249    /// <param name="enableAudioVbrEncoding">Optional. Whether to enable Audio Encoding.</param>
 250    /// <response code="200">Audio stream returned.</response>
 251    /// <returns>A <see cref="FileResult"/> containing the audio file.</returns>
 252    [HttpGet("{itemId}/stream.{container}", Name = "GetAudioStreamByContainer")]
 253    [HttpHead("{itemId}/stream.{container}", Name = "HeadAudioStreamByContainer")]
 254    [ProducesResponseType(StatusCodes.Status200OK)]
 255    [ProducesAudioFile]
 256    public async Task<ActionResult> GetAudioStreamByContainer(
 257        [FromRoute, Required] Guid itemId,
 258        [FromRoute, Required] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string container,
 259        [FromQuery] bool? @static,
 260        [FromQuery] string? @params,
 261        [FromQuery] string? tag,
 262        [FromQuery, ParameterObsolete] string? deviceProfileId,
 263        [FromQuery] string? playSessionId,
 264        [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? segmentContainer,
 265        [FromQuery] int? segmentLength,
 266        [FromQuery] int? minSegments,
 267        [FromQuery] string? mediaSourceId,
 268        [FromQuery] string? deviceId,
 269        [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? audioCodec,
 270        [FromQuery] bool? enableAutoStreamCopy,
 271        [FromQuery] bool? allowVideoStreamCopy,
 272        [FromQuery] bool? allowAudioStreamCopy,
 273        [FromQuery] int? audioSampleRate,
 274        [FromQuery] int? maxAudioBitDepth,
 275        [FromQuery] int? audioBitRate,
 276        [FromQuery] int? audioChannels,
 277        [FromQuery] int? maxAudioChannels,
 278        [FromQuery] string? profile,
 279        [FromQuery] [RegularExpression(EncodingHelper.LevelValidationRegex)] string? level,
 280        [FromQuery] float? framerate,
 281        [FromQuery] float? maxFramerate,
 282        [FromQuery] bool? copyTimestamps,
 283        [FromQuery] long? startTimeTicks,
 284        [FromQuery] int? width,
 285        [FromQuery] int? height,
 286        [FromQuery] int? videoBitRate,
 287        [FromQuery] int? subtitleStreamIndex,
 288        [FromQuery] SubtitleDeliveryMethod? subtitleMethod,
 289        [FromQuery] int? maxRefFrames,
 290        [FromQuery] int? maxVideoBitDepth,
 291        [FromQuery] bool? requireAvc,
 292        [FromQuery] bool? deInterlace,
 293        [FromQuery] bool? requireNonAnamorphic,
 294        [FromQuery] int? transcodingMaxAudioChannels,
 295        [FromQuery] int? cpuCoreLimit,
 296        [FromQuery] string? liveStreamId,
 297        [FromQuery] bool? enableMpegtsM2TsMode,
 298        [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? videoCodec,
 299        [FromQuery] [RegularExpression(EncodingHelper.ContainerValidationRegex)] string? subtitleCodec,
 300        [FromQuery] string? transcodeReasons,
 301        [FromQuery] int? audioStreamIndex,
 302        [FromQuery] int? videoStreamIndex,
 303        [FromQuery] EncodingContext? context,
 304        [FromQuery] Dictionary<string, string>? streamOptions,
 305        [FromQuery] bool enableAudioVbrEncoding = true)
 306    {
 307        StreamingRequestDto streamingRequest = new StreamingRequestDto
 308        {
 309            Id = itemId,
 310            Container = container,
 311            Static = @static ?? false,
 312            Params = @params,
 313            Tag = tag,
 314            PlaySessionId = playSessionId,
 315            SegmentContainer = segmentContainer,
 316            SegmentLength = segmentLength,
 317            MinSegments = minSegments,
 318            MediaSourceId = mediaSourceId,
 319            DeviceId = deviceId,
 320            AudioCodec = audioCodec,
 321            EnableAutoStreamCopy = enableAutoStreamCopy ?? true,
 322            AllowAudioStreamCopy = allowAudioStreamCopy ?? true,
 323            AllowVideoStreamCopy = allowVideoStreamCopy ?? true,
 324            AudioSampleRate = audioSampleRate,
 325            MaxAudioChannels = maxAudioChannels,
 326            AudioBitRate = audioBitRate,
 327            MaxAudioBitDepth = maxAudioBitDepth,
 328            AudioChannels = audioChannels,
 329            Profile = profile,
 330            Level = level,
 331            Framerate = framerate,
 332            MaxFramerate = maxFramerate,
 333            CopyTimestamps = copyTimestamps ?? false,
 334            StartTimeTicks = startTimeTicks,
 335            Width = width,
 336            Height = height,
 337            VideoBitRate = videoBitRate,
 338            SubtitleStreamIndex = subtitleStreamIndex,
 339            SubtitleMethod = subtitleMethod ?? SubtitleDeliveryMethod.Encode,
 340            MaxRefFrames = maxRefFrames,
 341            MaxVideoBitDepth = maxVideoBitDepth,
 342            RequireAvc = requireAvc ?? false,
 343            DeInterlace = deInterlace ?? false,
 344            RequireNonAnamorphic = requireNonAnamorphic ?? false,
 345            TranscodingMaxAudioChannels = transcodingMaxAudioChannels,
 346            CpuCoreLimit = cpuCoreLimit,
 347            LiveStreamId = liveStreamId,
 348            EnableMpegtsM2TsMode = enableMpegtsM2TsMode ?? false,
 349            VideoCodec = videoCodec,
 350            SubtitleCodec = subtitleCodec,
 351            TranscodeReasons = transcodeReasons,
 352            AudioStreamIndex = audioStreamIndex,
 353            VideoStreamIndex = videoStreamIndex,
 354            Context = context ?? EncodingContext.Static,
 355            StreamOptions = streamOptions,
 356            EnableAudioVbrEncoding = enableAudioVbrEncoding
 357        };
 358
 359        return await _audioHelper.GetAudioStream(_transcodingJobType, streamingRequest).ConfigureAwait(false);
 360    }
 361}