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

can't chromecast content that is castable #261

Open
brianjmurrell opened this issue Feb 20, 2017 · 12 comments
Open

can't chromecast content that is castable #261

brianjmurrell opened this issue Feb 20, 2017 · 12 comments

Comments

@brianjmurrell
Copy link

I have some TV programs on my MythBE that are in Chromecast-able format but the Android FE is saying they are not castable.

The test I am using to verify they are castable (beyond using tools like ffprobe, etc.) is to use stream2chromecast to cast them directly from a Linux machine to a Chromecast.

While I realise that stream2chromecast can transcode files not in the right format, I don't think it does so without the -transcode argument, which I am not using. Additionally, I can see that stream2chromecast is not starting an ffmpeg process to do any transcoding yet the content is successfully playing.

I am sure you will want some information about the file I am trying to play. I'm not sure what your preferred tool for that is but here is what ffinfo says about the file:

$ ffprobe 3006_20170218235900.mkv
ffprobe version 3.2.2 Copyright (c) 2007-2016 the FFmpeg developers
  built with gcc 6.3.1 (GCC) 20161221 (Red Hat 6.3.1-1)
  configuration: --arch=x86_64 --bindir=/usr/bin --datadir=/usr/share/ffmpeg --disable-debug --disable-static --disable-stripping --enable-avfilter --enable-avresample --enable-bzlib --enable-cuda --enable-cuvid --enable-libnpp --enable-doc --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gpl --enable-iconv --enable-libass --enable-libbluray --enable-libcdio --enable-libdc1394 --enable-libebur128 --enable-libfdk-aac --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libkvazaar --enable-libmfx --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libv4l2 --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxcb-shm --enable-libxcb-xfixes --enable-libxcb-shape --enable-libxvid --enable-libzvbi --enable-lzma --enable-nonfree --enable-openal --enable-opencl --enable-nvenc --enable-opengl --enable-postproc --enable-pthreads --enable-sdl2 --enable-shared --enable-version3 --enable-x11grab --enable-xlib --enable-zlib --extra-cflags='-I/usr/include/nvenc -I/usr/include/cuda' --incdir=/usr/include/ffmpeg --libdir=/usr/lib64 --mandir=/usr/share/man --optflags='-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --prefix=/usr --shlibdir=/usr/lib64 --enable-runtime-cpudetect
  libavutil      55. 34.100 / 55. 34.100
  libavcodec     57. 64.101 / 57. 64.101
  libavformat    57. 56.100 / 57. 56.100
  libavdevice    57.  1.100 / 57.  1.100
  libavfilter     6. 65.100 /  6. 65.100
  libavresample   3.  1.  0 /  3.  1.  0
  libswscale      4.  2.100 /  4.  2.100
  libswresample   2.  3.100 /  2.  3.100
  libpostproc    54.  1.100 / 54.  1.100
Input #0, matroska,webm, from '3006_20170218235900.mkv':
  Metadata:
    CREATION_TIME   : 2017-02-19T01:01:02Z
    ENCODER         : Lavf55.12.0
  Duration: 01:00:50.98, start: 0.046000, bitrate: 1401 kb/s
    Stream #0:0: Video: h264 (High), yuv420p(tv, smpte170m/smpte170m/bt709, progressive), 714x360 [SAR 8:9 DAR 238:135], SAR 214:241 DAR 12733:7230, 29.97 fps, 29.97 tbr, 1k tbn, 59.94 tbc (default)
    Stream #0:1: Audio: aac (LC), 48000 Hz, stereo, fltp (default)
    Metadata:
      title           : Stereo
    Stream #0:2: Audio: vorbis, 48000 Hz, stereo, fltp
    Metadata:
      title           : Stereo

As you can see, it is an mkv/webm container with an h.264 (high profile) video stream and both aac and vorbis audio streams in it.

@dmfrey
Copy link
Contributor

dmfrey commented Feb 20, 2017 via email

@brianjmurrell
Copy link
Author

So to be clear, I am not (and do not want to) HLS transcoding. The content I want to play lives on the BE in castable format natively.

@dmfrey
Copy link
Contributor

dmfrey commented Feb 20, 2017 via email

@brianjmurrell
Copy link
Author

By castable I mean that it is content (i.e. codecs, container, etc.) that meets Chromecast's requirements to be playable. But it is in that format on disk so does not need transcoding (i.e. by HLS). It does have a .mkv extension but is a webm format, according to ffprobe and stream2chromecast since it also does not need to transcode it to play it. It streams it right from disk to the Chromecast.

The app will play .mp4 or .m3u8 (HLS)

But we all understand that the extension of a filename is quite meaningless and nothing more than a hint being provided by the person who named the file as to what might be in it. My file could have an extension of ".foobar" but it's still a Chromecast playable H.264 High Profile stream in WebM container.

Can you run /Dvr/GetRecordedList and extract for me some of your entries that are in this format you want to stream

So to continue with the example file that I refer to above as playable by the Chromecast:

    <Program>
      <StartTime>2017-02-19T00:00:00Z</StartTime>
      <EndTime>2017-02-19T01:00:00Z</EndTime>
      <Title>W5</Title>
      <SubTitle>Creep Out; Electric Pow Wow</SubTitle>
      <Category>Newsmagazine</Category>
      <CatType>series</CatType>
      <Repeat>false</Repeat>
      <VideoProps>0</VideoProps>
      <AudioProps>1</AudioProps>
      <SubProps>1</SubProps>
      <SeriesId>EP01194508</SeriesId>
      <ProgramId>EP011945080246</ProgramId>
      <Stars>0</Stars>
      <LastModified>2017-02-19T02:19:03Z</LastModified>
      <ProgramFlags>5</ProgramFlags>
      <Airdate>2017-02-18</Airdate>
      <Description>Catching the Creep Catchers; a group that blends electronic music with First Nations music.</Description>
      <Inetref>ttvdb.py_277006</Inetref>
      <Season>0</Season>
      <Episode>0</Episode>
      <TotalEpisodes>0</TotalEpisodes>
      <FileSize>639445462</FileSize>
      <FileName>3006_20170218235900.mkv</FileName>
      <HostName>pvr</HostName>
      <Channel>
        <ChanId>3006</ChanId>
        <ChanNum>6</ChanNum>
        <CallSign>CJOH</CallSign>
        <IconURL/>
        <ChannelName>CJOH</ChannelName>
        <MplexId>32767</MplexId>
        <ServiceId>0</ServiceId>
        <ATSCMajorChan>6</ATSCMajorChan>
        <ATSCMinorChan>0</ATSCMinorChan>
        <Format>Default</Format>
        <FrequencyId>6</FrequencyId>
        <FineTune>0</FineTune>
        <ChanFilters/>
        <SourceId>3</SourceId>
        <InputId>0</InputId>
        <CommFree>false</CommFree>
        <UseEIT>false</UseEIT>
        <Visible>true</Visible>
        <XMLTVID>10127</XMLTVID>
        <DefaultAuth/>
        <Programs/>
      </Channel>
      <Recording>
        <RecordedId>4656</RecordedId>
        <Status>Recorded</Status>
        <Priority>0</Priority>
        <StartTs>2017-02-18T23:59:00Z</StartTs>
        <EndTs>2017-02-19T01:00:00Z</EndTs>
        <FileSize>1307951136</FileSize>
        <FileName>3006_20170218235900.mkv</FileName>
        <HostName>pvr</HostName>
        <LastModified>2017-02-19T02:19:03Z</LastModified>
        <RecordId>1975</RecordId>
        <RecGroup>Mom &amp; Dad</RecGroup>
        <PlayGroup>Default</PlayGroup>
        <StorageGroup>Default</StorageGroup>
        <RecType>0</RecType>
        <DupInType>15</DupInType>
        <DupMethod>6</DupMethod>
        <EncoderId>0</EncoderId>
        <EncoderName/>
        <Profile>Default</Profile>
      </Recording>
      <Artwork>
        <ArtworkInfos>
          <ArtworkInfo>
            <URL>/Content/GetImageFile?StorageGroup=Fanart&amp;FileName=/ttvdb.py_277006_fanart.jpg</URL>
            <FileName>myth://Fanart@pvr/ttvdb.py_277006_fanart.jpg</FileName>
            <StorageGroup>Fanart</StorageGroup>
            <Type>fanart</Type>
          </ArtworkInfo>
          <ArtworkInfo>
            <URL>/Content/GetImageFile?StorageGroup=Banners&amp;FileName=/ttvdb.py_277006_banner.jpg</URL>
            <FileName>myth://Banners@pvr/ttvdb.py_277006_banner.jpg</FileName>
            <StorageGroup>Banners</StorageGroup>
            <Type>banner</Type>
          </ArtworkInfo>
        </ArtworkInfos>
      </Artwork>
      <Cast>
        <CastMembers>
          <CastMember>
            <Name>Victor Malarek</Name>
            <CharacterName/>
            <Role/>
            <TranslatedRole/>
          </CastMember>
          <CastMember>
            <Name>Anton Koschany</Name>
            <CharacterName/>
            <Role>executive_producer</Role>
            <TranslatedRole>Executive Producer</TranslatedRole>
          </CastMember>
          <CastMember>
            <Name>Kevin Newman</Name>
            <CharacterName/>
            <Role>host</Role>
            <TranslatedRole>Host</TranslatedRole>
          </CastMember>
          <CastMember>
            <Name>Lloyd Robertson</Name>
            <CharacterName/>
            <Role>host</Role>
            <TranslatedRole>Host</TranslatedRole>
          </CastMember>
          <CastMember>
            <Name>Sandie Rinaldo</Name>
            <CharacterName/>
            <Role>host</Role>
            <TranslatedRole>Host</TranslatedRole>
          </CastMember>
          <CastMember>
            <Name>Lisa LaFlamme</Name>
            <CharacterName/>
            <Role>host</Role>
            <TranslatedRole>Host</TranslatedRole>
          </CastMember>
        </CastMembers>
      </Cast>
    </Program>

@dmfrey
Copy link
Contributor

dmfrey commented Feb 24, 2017

I understand what you are saying, however, I still need to be able to check against the data I have available and compare it to the supported media types published. I can't check the actual file from within the app, other than playing it and waiting for a failure, which is not a pleasant experience.

I will add .mkv extension for recordings. Are there any others I should add? .mp4, .mkv, and .m3u8 should cover the most the types typical users will have, correct?

@brianjmurrell
Copy link
Author

Are there any others I should add? .mp4, .mkv, and .m3u8 should cover the most the types typical users will have, correct

I'm not an expert on Chromecast or containers but those seem a reasonable start.

As for actually looking at the file contents, as an example, ffprobe is able to determine a lot about a (webm) file by just opening it and reading 64K. It really would be a pity if the casting API didn't have a function for doing such a thing and worthy of an RFE if it didn't I would think.

@pot8oe
Copy link
Contributor

pot8oe commented Feb 24, 2017

@dmfrey Would the MediaMetadataRetriever provide the necessary information? There is also the question if the setDataSource(string uri ...) function works with URI's that are not local on the device.

https://developer.android.com/reference/android/media/MediaMetadataRetriever.html#setDataSource(java.lang.String, java.util.Map<java.lang.String, java.lang.String>)

There is another project I have never used but claims to pull metadata across different protocols.

https://github.com/wseemann/FFmpegMediaMetadataRetriever

@dmfrey
Copy link
Contributor

dmfrey commented Feb 24, 2017 via email

@dmfrey
Copy link
Contributor

dmfrey commented Feb 28, 2017

i've took a look at both approaches. Each fails outright. I am guessing it is some change in the underlying os code. When I drill into the methods, they typically are just throwing some kind of RuntimeException. So I am not sure if the MediaMetadataRetriever is going to be available going forward or not.

@dmfrey
Copy link
Contributor

dmfrey commented Apr 13, 2017

@brianjmurrell Along with the previous update, you should now be able to play at least mkv container formats from any recording or video details screen in the develop branch. Please let me know if this is now working for you.

As for inspecting the media file itself, is this something we could request be added to the backend and the data input into Mythtv Services API? Maybe it could be a separate endpoint we could call on-demand that would perform the probe and return the response? ( @billmeek something to think about)

@dmfrey
Copy link
Contributor

dmfrey commented Apr 13, 2017

@brianjmurrell sidebar...do you run this as a user job on your backend? If so, how quickly does it occur? I have been having horrible luck with the HLS transcoding as of late. The last update to my backend seems to have broken it completely. I get a stream, but it just won't play it.

@brianjmurrell
Copy link
Author

brianjmurrell commented Apr 15, 2017

Please let me know if this is now working for you.

I don't really have the skill-set (i.e. I don't even know what the toolset is) to build an install-able .apk from source. Is there a (i.e. nightly) build being produced somewhere that I can load?

As for inspecting the media file itself, is this something we could request be added to the backend and the data input into Mythtv Services API

I suppose this is one approach. This requires that the Myth developers actually be willing to land a patch to do so. Alternately, you could simply fetch enough of the file in your app to test and know what the type is.

do you run this as a user job on your backend?

Are you referring to the non-on-demand transcoding? If so, yes.

If so, how quickly does it occur?

As quickly as the hardware can do an encoding, so as you could guess, it's entirely hardware dependent. But the job is started as a user job the moment the episode has completed recording (not the moment it starts recording). I don't have any demands on being able to watch a recording while it's being recorded so waiting is good enough for me to not need to try to engineer a real-time encoding process with the complications of reading to EOF, etc.

horrible luck with the HLS transcoding as of late

I have never had good luck with it. It seems pretty flaky and buggy in my experience.

I much prefer to just stream regular files. It's a known working entity (for the moment).

Sadly, in fact (after more than a decade of using it) I might be abandoning all of MythTV but for just the task of scheduling and recording (until I can find a replacement for that too). I will probably write a user job to move the recording to somewhere where Kodi can just access it as regular media the way Kodi handles all other media and then "delete" (i.e. the existence of the episode) it from the database.

The only use I had for leaving it all in Myth (until now) was using the MythTV Kodi plugin to access it, but that has just become more trouble than it's worth when Kodi is perfectly happy to just deal with regular files instead of having to work through the Myth protocol(s) (i.e. both the native and the Services API).

The reality here and now is that Kodi is the front-end. It is for a lot of people. I came to this conclusion when I gave it a spin when I was finding that it could play recordings on the exact same hardware and O/S that the MythFE (0.28) was struggling (with great difficultly) with and it was just easier to use Kodi than to try to continue debugging the MythFE problem.

I had really just intended Kodi to be the proof that the problem was not hardware nor O/S but when I got a better look at Kodi, there was no looking back. After having used it for over a year now Kodi is just so much richer than the MythFE.

The only gap I have to fill is Chromecasting from Kodi on Android.

That said, while I still have a MythBE up here and can reproduce the problem this ticket reports, I am happy to test your FE with it and my transcoded recordings if you can point me at an .apk to test with. Seems worth while to do that given the effort you and I have both invested in this ticket to close it out with success.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants