Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

undocumented opus channel support #1361

Open
sevenrats opened this issue Sep 11, 2023 · 9 comments
Open

undocumented opus channel support #1361

sevenrats opened this issue Sep 11, 2023 · 9 comments
Labels
bug Something isn't working

Comments

@sevenrats
Copy link
Member

how many channels does opus support? its definitely not 5.1
roku won't fail on this but it plays a horrid screaching glitch sound.

@cewert
Copy link
Member

cewert commented Sep 12, 2023

how many channels does opus support? its definitely not 5.1 roku won't fail on this but it plays a horrid screaching glitch sound.

Opus supports up to 255 audio channels - see here

You were testing against unstable, correct? Can you paste the debug log so I can see your device profile?

Was the file direct playing, direct streaming, or transcoding?

@sevenrats
Copy link
Member Author

sevenrats commented Sep 12, 2023

i have no doubt that opus does. I'm just referring to opus on the roku, which does not. it appears to only support up to stereo.
the file directplays without my changes and the audio just screams. wihth my changes it directstreams as expected

@sevenrats
Copy link
Member Author

profile =       <Component: roAssociativeArray> =
{
    AppStoreUrl: "https://channelstore.roku.com/details/cc5e559d08d9ec87c5f30dcebdeebc12/jellyfin"
    DeviceProfile: <Component: roAssociativeArray>
    PlayableMediaTypes: <Component: roArray>
    SupportedCommands: <Component: roArray>
    SupportsContentUploading: false
    SupportsMediaControl: false
    SupportsPersistentIdentifier: false
    SupportsSync: false
}
profile.DeviceProfile =         <Component: roAssociativeArray> =
{
    CodecProfiles: <Component: roArray>
    ContainerProfiles: <Component: roArray>
    DirectPlayProfiles: <Component: roArray>
    FriendlyName: "Roku Streaming Stick"
    Id: "60a36e5b-8a6c-56ca-8f20-82c0801227a0"
    Identification: <Component: roAssociativeArray>
    Manufacturer: "Roku"
    MaxStaticBitrate: 100000000
    MaxStreamingBitrate: 120000000
    ModelDescription: "Type: STB"
    ModelName: "Roku Streaming Stick+"
    ModelNumber: "3810X"
    MusicStreamingTranscodingBitrate: 192000
    Name: "Official Roku Client"
    SerialNumber: ""
    SubtitleProfiles: <Component: roArray>
    TranscodingProfiles: <Component: roArray>
}
profile.DeviceProfile.CodecProfiles =
<Component: roAssociativeArray> =
{
    Conditions: <Component: roArray>
    Type: "VideoAudio"
}
<Component: roAssociativeArray> =
{
    Condition: "LessThanEqual"
    IsRequired: false
    Property: "AudioChannels"
    Value: "6"
}
<Component: roAssociativeArray> =
{
    Codec: "h264"
    Conditions: <Component: roArray>
    Type: "Video"
}
<Component: roAssociativeArray> =
{
    Condition: "NotEquals"
    IsRequired: false
    Property: "IsAnamorphic"
    Value: "true"
}
<Component: roAssociativeArray> =
{
    Condition: "EqualsAny"
    IsRequired: false
    Property: "VideoProfile"
    Value: "high|main"
}
<Component: roAssociativeArray> =
{
    Condition: "EqualsAny"
    IsRequired: false
    Property: "VideoRangeType"
    Value: "SDR"
}
<Component: roAssociativeArray> =
{
    Condition: "LessThanEqual"
    IsRequired: false
    Property: "VideoLevel"
    Value: "42"
}
<Component: roAssociativeArray> =
{
    Condition: "LessThanEqual"
    IsRequired: true
    Property: "VideoBitrate"
    Value: "10000000"
}
<Component: roAssociativeArray> =
{
    Codec: "hevc"
    Conditions: <Component: roArray>
    Type: "Video"
}
<Component: roAssociativeArray> =
{
    Condition: "NotEquals"
    IsRequired: false
    Property: "IsAnamorphic"
    Value: "true"
}
<Component: roAssociativeArray> =
{
    Condition: "EqualsAny"
    IsRequired: false
    Property: "VideoProfile"
    Value: "main|main 10"
}
<Component: roAssociativeArray> =
{
    Condition: "EqualsAny"
    IsRequired: false
    Property: "VideoRangeType"
    Value: "SDR"
}
<Component: roAssociativeArray> =
{
    Condition: "LessThanEqual"
    IsRequired: false
    Property: "VideoLevel"
    Value: "153"
}
<Component: roAssociativeArray> =
{
    Condition: "LessThanEqual"
    IsRequired: true
    Property: "VideoBitrate"
    Value: "40000000"
}
profile.DeviceProfile.ContainerProfiles =       <Component: roArray> =
[
]
profile.DeviceProfile.DirectPlayProfiles =
<Component: roAssociativeArray> =
{
    AudioCodec: "mp3,mp2,pcm,ac3,flac,aac"
    Container: "ts"
    Type: "Video"
    VideoCodec: "h264,mpeg4 avc,hevc,h265,mpeg4"
}
<Component: roAssociativeArray> =
{
    AudioCodec: "mp3,mp2,pcm,ac3,wma,flac,alac,aac,opus,wmapro,vorbis"
    Container: "mkv,webm"
    Type: "Video"
    VideoCodec: "h264,mpeg4 avc,vp9,hevc,h265,mpeg4"
}
<Component: roAssociativeArray> =
{
    AudioCodec: "ac3,wma,aac,wmapro"
    Container: "ism"
    Type: "Video"
    VideoCodec: "h264,mpeg4 avc,hevc,h265,mpeg4"
}
<Component: roAssociativeArray> =
{
    AudioCodec: "mp3,mp2,ac3,alac,aac"
    Container: "mp4,mov,m4v"
    Type: "Video"
    VideoCodec: "h264,mpeg4 avc,hevc,h265,mpeg4"
}
<Component: roAssociativeArray> =
{
    AudioCodec: "mp3,mp2,ac3,aac"
    Container: "hls"
    Type: "Video"
    VideoCodec: "h264,mpeg4 avc,hevc,h265,mpeg4"
}
<Component: roAssociativeArray> =
{
    AudioCodec: "aac"
    Container: "dash"
    Type: "Video"
    VideoCodec: "h264,mpeg4 avc,hevc,h265,mpeg4"
}
<Component: roAssociativeArray> =
{
    Container: "mp3,mp2,pcm,ac3,wma,flac,alac,aac,opus,wmapro,vorbis"
    Type: "Audio"
}
profile.DeviceProfile.SubtitleProfiles =
<Component: roAssociativeArray> =
{
    Format: "vtt"
    Method: "External"
}
<Component: roAssociativeArray> =
{
    Format: "srt"
    Method: "External"
}
<Component: roAssociativeArray> =
{
    Format: "ttml"
    Method: "External"
}
<Component: roAssociativeArray> =
{
    Format: "sub"
    Method: "External"
}
profile.DeviceProfile.TranscodingProfiles =
<Component: roAssociativeArray> =
{
    AudioCodec: "mp3"
    Container: "mp3"
    Context: "Streaming"
    MaxAudioChannels: "6"
    Protocol: "http"
    Type: "Audio"
}
<Component: roAssociativeArray> =
{
    AudioCodec: "mp3"
    Container: "mp3"
    Context: "Static"
    MaxAudioChannels: "6"
    Protocol: "http"
    Type: "Audio"
}
<Component: roAssociativeArray> =
{
    AudioCodec: "aac"
    Container: "ts"
    Context: "Streaming"
    MaxAudioChannels: "2"
    Protocol: "http"
    Type: "Audio"
}
<Component: roAssociativeArray> =
{
    AudioCodec: "aac"
    Container: "ts"
    Context: "Static"
    MaxAudioChannels: "2"
    Protocol: "http"
    Type: "Audio"
}
<Component: roAssociativeArray> =
{
    AudioCodec: "ac3"
    Container: "ac3"
    Context: "Streaming"
    MaxAudioChannels: "6"
    Protocol: "http"
    Type: "Audio"
}
<Component: roAssociativeArray> =
{
    AudioCodec: "ac3"
    Container: "ac3"
    Context: "Static"
    MaxAudioChannels: "6"
    Protocol: "http"
    Type: "Audio"
}
<Component: roAssociativeArray> =
{
    audiocodec: "ac3,aac,mp3,flac,pcm"
    BreakOnNonKeyFrames: false
    conditions: <Component: roArray>
    Container: "ts"
    Context: "Streaming"
    MaxAudioChannels: "6"
    MinSegments: 1
    Protocol: "hls"
    Type: "Video"
    VideoCodec: "hevc,h265,h264,mpeg4 avc"
}
<Component: roAssociativeArray> =
{
    Condition: "LessThanEqual"
    IsRequired: true
    Property: "Width"
    Value: "1920"
}
<Component: roAssociativeArray> =
{
    Condition: "LessThanEqual"
    IsRequired: true
    Property: "Height"
    Value: "1080"
}
<Component: roAssociativeArray> =
{
    audiocodec: "ac3,aac,mp3,alac"
    BreakOnNonKeyFrames: false
    conditions: <Component: roArray>
    Container: "mp4"
    Context: "Streaming"
    MaxAudioChannels: "6"
    MinSegments: 1
    Protocol: "hls"
    Type: "Video"
    VideoCodec: "hevc,h265,h264,mpeg4 avc"
}
<Component: roAssociativeArray> =
{
    Condition: "LessThanEqual"
    IsRequired: true
    Property: "Width"
    Value: "1920"
}
<Component: roAssociativeArray> =
{
    Condition: "LessThanEqual"
    IsRequired: true
    Property: "Height"
    Value: "1080"
}
profile.PlayableMediaTypes =    <Component: roArray> =
[
    "Audio"
    "Video"
    "Photo"
]
profile.SupportedCommands =     <Component: roArray> =
[
]

@slickdakine
Copy link

I can confirm this. I would also like to add the Roku Jellfin app also does not map the channels correctly. When playing a speaker config video with 7.1 Opus, the center channel comes out the right speaker, and the right speaker comes out the rear. They are mapped wrong. This also happens on 5.1 opus encoded videos. When playing, clipping can also be heard on louder sounds. I tested this with JellyCon on Kodi and the channels are correctly mapped. Kodi playing the files directly are also correctly mapped. So this seems to be a problem specific to the Roku Jellyfin app with no transcoding and direct play.

@cewert
Copy link
Member

cewert commented Jan 13, 2024

I can confirm this.

@slickdakine What exactly are you confirming? Do you hear a "screeching glitch sound" when playing multichannel opus audio files?

@slickdakine
Copy link

I can confirm this.

@slickdakine What exactly are you confirming? Do you hear a "screeching glitch sound" when playing multichannel opus audio files?

Hi cewert,

I'm confirming the Jellyfin Roku app does not handle multichannel opus files correctly. I don't get the screeching, but I do get clipping on louder sounds and mismatched channels. The multichannel Opus streams are "Direct Playing" as indicated within the roku jellyfin app. My Roku TV is connected through HDMI ARC to a Yamaha receiver in a 7.1 passthrough setup. My Kodi box natively and using the jellycon app play the multichannel opus files without issue.

I double checked the channel mismatch with 7.1 and 5.1 sound check mkv containers that were converted from DTS to Opus with handbrake. The channel mismatch is only present when playing the multichannel Opus mkv direct playing in the Roku Jellyfin app.

On a side note, the Roku Plex app won't decode the Opus, it transcodes to AC3.
Maybe because of this?

Thanks!

@slickdakine
Copy link

I'd like to followup with some more testing I did. I plugged a USB stick into my ROKU TV, and tried to play those multichannel opus mkvs. Using the Roku media player, I had no sound when playing the 7.1 opus mkv. The 7.1 DTS-MA version played fine. I then tried the 5.1 opus mkv. It played it back, but again the channels were mismatched. The 5.1 DTS-MA played back fine.

Based on this testing, it looks like its a problem with the underlying Roku software which the Jellyfin app is running on. I think the best work around would be to simply transcode opus tracks to a format the Roku works better with. Is there a way to force transcoding of audio when dealing with Roku clients? I looked around and some suggested setting the maxium bitrate to do that.

@cewert
Copy link
Member

cewert commented Feb 3, 2024

@slickdakine thanks for all the info. I agree with your conclusion that we should convert to another multichannel codec the device supports like in #1466

Is there a way to force transcoding of audio when dealing with Roku clients? I looked around and some suggested setting the maxium bitrate to do that.

That's a popular feature request but no not at the moment. The max bitrate is the closest thing that I know of.

@slickdakine
Copy link

I'd like to followup with some more testing I did. I plugged a USB stick into my ROKU TV, and tried to play those multichannel opus mkvs. Using the Roku media player, I had no sound when playing the 7.1 opus mkv. The 7.1 DTS-MA version played fine. I then tried the 5.1 opus mkv. It played it back, but again the channels were mismatched. The 5.1 DTS-MA played back fine.

Based on this testing, it looks like its a problem with the underlying Roku software which the Jellyfin app is running on. I think the best work around would be to simply transcode opus tracks to a format the Roku works better with. Is there a way to force transcoding of audio when dealing with Roku clients? I looked around and some suggested setting the maxium bitrate to do that.

I did some more testing, and I wonder if its the order that the Roku software uses to decode the opus channels.
Again this seems to be a Roku problem, but I have no idea who to contact about it. If you look at the Mediainfo I ran on the soundcheck files I'm using, the ones encoded in Opus have a different channel order than the DTS ones. Now Kodi correctly matches them but, but again the Roku does not. Could the programmers just set a default match pattern to match them instead of actually matching them by name?
In conclusion I'm curious if the problem is with the channel order encoded in the MKVs and how Roku matches them.
OpusConfig

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants