Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save dmgolembiowski/7ac81ae51da58fa83d9f031f72f434ab to your computer and use it in GitHub Desktop.
Save dmgolembiowski/7ac81ae51da58fa83d9f031f72f434ab to your computer and use it in GitHub Desktop.

Getting a streamable link is done by the client.

You basically need to send the service a detailed list of the type of media you can play, and it will give you a transcode URL to call if it thinks you need transcoding in order to play this file.

If you don't and can play the file directly it won't give you a transcode URL.

POST <server_address>/Items/<item_id>/PlaybackInfo?UserId=<current_user_id>

Request body

{
  "DeviceProfile": {
    "MaxStreamingBitrate": 120000000,
    "MaxStaticBitrate": 100000000,
    "MusicStreamingTranscodingBitrate": 384000,
    "DirectPlayProfiles": [
      {
        "Container": "webm",
        "Type": "Video",
        "VideoCodec": "vp8,vp9",
        "AudioCodec": "vorbis"
      },
      {
        "Container": "mp4,m4v",
        "Type": "Video",
        "VideoCodec": "h264,vp8,vp9",
        "AudioCodec": "aac,mp3,ac3,eac3,flac,alac,vorbis"
      },
      {
        "Container": "mov",
        "Type": "Video",
        "VideoCodec": "h264",
        "AudioCodec": "aac,mp3,ac3,eac3,flac,alac,vorbis"
      },
      {
        "Container": "mp3",
        "Type": "Audio"
      },
      {
        "Container": "aac",
        "Type": "Audio"
      },
      {
        "Container": "m4a",
        "AudioCodec": "aac",
        "Type": "Audio"
      },
      {
        "Container": "m4b",
        "AudioCodec": "aac",
        "Type": "Audio"
      },
      {
        "Container": "flac",
        "Type": "Audio"
      },
      {
        "Container": "alac",
        "Type": "Audio"
      },
      {
        "Container": "m4a",
        "AudioCodec": "alac",
        "Type": "Audio"
      },
      {
        "Container": "m4b",
        "AudioCodec": "alac",
        "Type": "Audio"
      },
      {
        "Container": "webma",
        "Type": "Audio"
      },
      {
        "Container": "webm",
        "AudioCodec": "webma",
        "Type": "Audio"
      },
      {
        "Container": "wav",
        "Type": "Audio"
      }
    ],
    "TranscodingProfiles": [
      {
        "Container": "aac",
        "Type": "Audio",
        "AudioCodec": "aac",
        "Context": "Streaming",
        "Protocol": "hls",
        "MaxAudioChannels": "6",
        "MinSegments": "2",
        "BreakOnNonKeyFrames": true
      },
      {
        "Container": "aac",
        "Type": "Audio",
        "AudioCodec": "aac",
        "Context": "Streaming",
        "Protocol": "http",
        "MaxAudioChannels": "6"
      },
      {
        "Container": "mp3",
        "Type": "Audio",
        "AudioCodec": "mp3",
        "Context": "Streaming",
        "Protocol": "http",
        "MaxAudioChannels": "6"
      },
      {
        "Container": "wav",
        "Type": "Audio",
        "AudioCodec": "wav",
        "Context": "Streaming",
        "Protocol": "http",
        "MaxAudioChannels": "6"
      },
      {
        "Container": "mp3",
        "Type": "Audio",
        "AudioCodec": "mp3",
        "Context": "Static",
        "Protocol": "http",
        "MaxAudioChannels": "6"
      },
      {
        "Container": "aac",
        "Type": "Audio",
        "AudioCodec": "aac",
        "Context": "Static",
        "Protocol": "http",
        "MaxAudioChannels": "6"
      },
      {
        "Container": "wav",
        "Type": "Audio",
        "AudioCodec": "wav",
        "Context": "Static",
        "Protocol": "http",
        "MaxAudioChannels": "6"
      },
      {
        "Container": "ts",
        "Type": "Video",
        "AudioCodec": "aac,mp3,ac3,eac3",
        "VideoCodec": "h264",
        "Context": "Streaming",
        "Protocol": "hls",
        "MaxAudioChannels": "6",
        "MinSegments": "2",
        "BreakOnNonKeyFrames": true
      },
      {
        "Container": "webm",
        "Type": "Video",
        "AudioCodec": "vorbis",
        "VideoCodec": "vpx",
        "Context": "Streaming",
        "Protocol": "http",
        "MaxAudioChannels": "6"
      },
      {
        "Container": "mp4",
        "Type": "Video",
        "AudioCodec": "aac,mp3,ac3,eac3,flac,alac,vorbis",
        "VideoCodec": "h264",
        "Context": "Static",
        "Protocol": "http"
      }
    ],
    "ContainerProfiles": [],
    "CodecProfiles": [
      {
        "Type": "Video",
        "Codec": "h264",
        "Conditions": [
          {
            "Condition": "NotEquals",
            "Property": "IsAnamorphic",
            "Value": "true",
            "IsRequired": false
          },
          {
            "Condition": "EqualsAny",
            "Property": "VideoProfile",
            "Value": "high|main|baseline|constrained baseline",
            "IsRequired": false
          },
          {
            "Condition": "LessThanEqual",
            "Property": "VideoLevel",
            "Value": "51",
            "IsRequired": false
          },
          {
            "Condition": "NotEquals",
            "Property": "IsInterlaced",
            "Value": "true",
            "IsRequired": false
          }
        ]
      },
      {
        "Type": "Video",
        "Codec": "hevc",
        "Conditions": [
          {
            "Condition": "NotEquals",
            "Property": "IsAnamorphic",
            "Value": "true",
            "IsRequired": false
          },
          {
            "Condition": "EqualsAny",
            "Property": "VideoProfile",
            "Value": "main|main 10",
            "IsRequired": false
          },
          {
            "Condition": "LessThanEqual",
            "Property": "VideoLevel",
            "Value": "183",
            "IsRequired": false
          },
          {
            "Condition": "NotEquals",
            "Property": "IsInterlaced",
            "Value": "true",
            "IsRequired": false
          }
        ]
      }
    ],
    "SubtitleProfiles": [
      {
        "Format": "vtt",
        "Method": "External"
      },
      {
        "Format": "ass",
        "Method": "External"
      },
      {
        "Format": "ssa",
        "Method": "External"
      }
    ],
    "ResponseProfiles": [
      {
        "Type": "Video",
        "Container": "m4v",
        "MimeType": "video/mp4"
      }
    ]
  }
}

That's the profile the web UI uses for the Safari (MP4's basically).

In return the server will give you something like this (remember the user might have multiple versions of the Movie (DVD vs Bluray, extended editions, directors cut, etc....), this list will contain info for each file):

{
  "MediaSources": [
    {
      "Protocol": "File",
      "Id": "bf22ec0d983592dda98b24346afa7735",
      "Type": "Default",
      "Container": "webm",
      "Size": 2188750848,
      "Name": "Camp Rock (2008)",
      "IsRemote": false,
      "ETag": "95706793fc3b7f3b84b35d6fbfd071d3",
      "RunTimeTicks": 56743358464,
      "SupportsTranscoding": true,
      "VideoType": "VideoFile",
      "MediaStreams": [
        {
          "Codec": "h264",
          "Height": 576,
          "Width": 720,
          "AverageFrameRate": 25,
          "RealFrameRate": 25,
          "Type": "Video",
          "AspectRatio": "16:9",
        },
        {
          "Codec": "ac3",
          "Language": "eng",
          "DisplayTitle": "En - Dolby Digital - 5.1 - Default",
          "Channels": 6,
          "SampleRate": 48000,
          "Type": "Audio"
        },
        {
          "Codec": "aac",
          "Language": "eng",
          "DisplayTitle": "En - AAC - Stereo",
          "BitRate": 192000,
          "Channels": 2,
          "Type": "Audio",
          "Index": 2
        },
        {
          "Codec": "ac3",
          "Language": "dan",
          "BitRate": 384000,
          "Channels": 6,
          "Type": "Audio"
        },
        {
          "Codec": "srt",
          "IsDefault": false,
          "IsForced": false,
          "Type": "Subtitle",
          "IsExternal": true,
          "DeliveryMethod": "External",
          "DeliveryUrl": "/Videos/<uuid>/Subtitles/5/0/Stream.vtt?api_key=....",
        }
      ],
      "MediaAttachments": [],
      "Formats": [],
      "Bitrate": 4237824,
      "RequiredHttpHeaders": {},
      "TranscodingUrl": "/videos/<item_id>/master.m3u8?<long chain of generated config options>",
      "TranscodingSubProtocol": "hls",
      "TranscodingContainer": "ts",
      "DefaultAudioStreamIndex": 1
    }
  ],
  "PlaySessionId": "fe2f0d6ba2e24b419f61c07683ce915b"
}

If the video is an MP4 you can just stream and play directly you won't get a TranscodingUrl option in the response.

That case you just use this URL:

<server_address>/Videos/\(mediaSource.Id)/stream.mp4
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment