MythTV-Clients / MythtvPlayerForAndroid

MythTV Player is an Android client for accessing content from a MythTV Backend
https://play.google.com/store/apps/details?id=org.mythtv.android
GNU General Public License v3.0
16 stars 7 forks source link

can't chromecast content that is castable #261

Open brianjmurrell opened 7 years ago

brianjmurrell commented 7 years ago

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 commented 7 years ago

Is it actually updating an entry in the live stream table, generating a live stream id and storing the filename of the original file? There is no correlation in the tables that a stream exists, other than the live stream table contains the original filename of the file that was converted. Please verify this in your DB as well as hitting the /Content/GetLiveStreamList services endpoint. The app is limited to the actions supported by the MythTV Services Endpoint.

On Mon, Feb 20, 2017 at 1:53 PM Brian J. Murrell notifications@github.com wrote:

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 https://github.com/Pat-Carter/stream2chromecast to cast them directly from a Linux machine to a Chromecast.

While I realise that stream2chromecast https://github.com/Pat-Carter/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 https://github.com/Pat-Carter/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.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/MythTV-Clients/MythtvPlayerForAndroid/issues/261, or mute the thread https://github.com/notifications/unsubscribe-auth/AA5yzP6Yd5fBcoGnPAzu2MXCNHMJzmecks5reeE7gaJpZM4MGhFK .

brianjmurrell commented 7 years ago

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 commented 7 years ago

What do you mean by castable. Are you transcoding it to mp4? What is the Ext? The app will play .mp4 or .m3u8 (HLS). Is there another one I should be considering. Can you run /Dvr/GetRecordedList and extract for me some of your entries that are in this format you want to stream?

On Mon, Feb 20, 2017 at 3:11 PM Brian J. Murrell notifications@github.com wrote:

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.

— You are receiving this because you commented.

Reply to this email directly, view it on GitHub https://github.com/MythTV-Clients/MythtvPlayerForAndroid/issues/261#issuecomment-281171373, or mute the thread https://github.com/notifications/unsubscribe-auth/AA5yzJJU6YcOCqFTz7iKV2qQmkeLEj-pks5refNdgaJpZM4MGhFK .

brianjmurrell commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

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 commented 7 years ago

@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 commented 7 years ago

Thanks Tom, I will give those projects a look.

On Fri, Feb 24, 2017, 9:44 AM Thomas G. Kenny Jr notifications@github.com wrote:

@dmfrey https://github.com/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

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/MythTV-Clients/MythtvPlayerForAndroid/issues/261#issuecomment-282308255, or mute the thread https://github.com/notifications/unsubscribe-auth/AA5yzOMrZRaQnWCCFxVip_5jyy39Uh_yks5rfuzXgaJpZM4MGhFK .

dmfrey commented 7 years ago

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 commented 7 years ago

@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 commented 7 years ago

@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 commented 7 years ago

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.