Freeview Deeplink (UK)

The UK based Freeview app (iOS) uses deeplinks to open up BBC, ITV, Channel 4 apps etc to play the stream for that channel. It’s really fluid and just automatically plays, but I can’t find anywhere what the deeplink is that it’s using. The only ones I can find open the app but don’t play it.

Long shot, but does anyone know what they might be or how to find them?

1 Like

@Naonak did you manage to find an answer for this?
Trial and error has revealed iPlayer links such as:

bbciplayer://channels/bbc_one

bbciplayer://channels/bbc_two

bbciplayer://channels/bbc_news24

1 Like

That’s useful thanks. Did you have any luck with ITV or 4?

I wasn’t able to find any, and did a lot of trial and error myself.

the list of apps:

freeview://
bbciplayer://
itvplayer://
all4://
my5://
uktvplay://
stv-player://
cbscatchup://

some examples:

bbciplayer://www.bbc.co.uk/iplayer/mobile/channels/bbc_one
bbciplayer://www.bbc.co.uk/iplayer/mobile/channels/bbc_three
bbciplayer://www.bbc.co.uk/iplayer/mobile/channels/cbeebies
bbciplayer://www.bbc.co.uk/iplayer/mobile/channels/bbc_news24
bbciplayer://www.bbc.co.uk/iplayer/mobile/channels/bbc_parliament

all4://views/on-now?channel=E4
all4://views/on-now?channel=F4
all4://views/on-now?channel=M4
all4://views/on-now?channel=4s #4seven

itvplayer://freeview_app/simulcast/itv
itvplayer://freeview_app/simulcast/itv2
itvplayer://freeview_app/simulcast/itv4
itvplayer://freeview_app/simulcast/itvbe

my5://watch/C5 #5
my5://watch/C7 #5USA
my5://watch/C6 #5STAR
my5://watch/C0 #5ACTION
my5://watch/C8 #5SELECT

the on-demand ones look like:

uktvplay://video/LDXA899W
cbscatchup://show/45036278
https://player.stv.tv/episode/210327
bbciplayer://www.bbc.co.uk/iplayer/mobile/episode/m0012vh3
all4://views/brands?brand=attack-the-block&programme=43601-001
itvplayer://freeview_app/play/1_8812_0001.005

3 Likes

Wow - thank you so much!

1 Like

Thank you @tmm1 for the info. Is there a resource you can recommend for how to get the correct string for the other apps?

It's pretty complicated unfortunately. Which app are you interested in?

Would you know the structure for the TVNZ+ app?

You'd have to check inside the manifest file in the apk

What are you looking for in the TVNZ+ app? all their streams are published on Matts page. Not hard to find.

I'm tinkering with the pyATV version of ah4c. I have it set up to launch the app and then use the Apple TV remote commands to get the stream going, but using deep links would be even better. Matt's links are great, but I'd like a backup as well as the ability to set things up like the folks with YouTubeTV and other sources that seem to be getting harder to use without tools like ah4c and ADBTuner.

Not strictly Freeview but do any of you UK users know what the deep links are for the live channel streams on Now TV (and Discovery+ for Eurosport)?

I’m presuming both apps utilise deep links because I use another app, TV Launcher, which is great and more or less an EPG which directly launches the appropriate app and starts the channel, so I assume that is using the deep links. I’d love to get this working with streamlinks in custom channels.

I’ve got some channels in with the associated epg data and I can easily get it to open the app (using nowtv:// and discoveryplus://), but I can’t figure out the required path to open the channel. I’ve tried getting some clues from launching in a web browser but the app links don’t seem to follow the same format.

TIA

1 Like

I'd be interested in that as well! Could someone tell me how I use these Deeplinks in Channels?

1 Like

After much searching and trial and error, I've managed to find the answer to my own question so sharing for others that want to do similar and to save you some time.

The format for Now TV deeplinks is...

nowtv://go/query/service_key/xxxx/play

You need to replace xxxx with the number for the channel. This is not the Sky Channel number, but you can find this number in the web address when launching in a desktop web browser. For example, Sky Sports News is 1314, Sky Sports F1 is 1306.

For Eurosport on Discovery+ the deeplink is....

discoveryplus://discoveryplus.com/channel/eurosport-1

For other channels replace the last bit, e.g., eurosport-2 or tnt-sports-1. You still have to click the watch now button in discovery+, I've not found the way around that yet.

1 Like

Hi Jon,

I'm very much a beginner and I've only been playing around to see what is possible. I did this by going into the server settings -> sources, and creating custom channels.

I set it up like this, just for Sky Sports News (from the Now Tv app) and ITV4 (from the ITVX app) for a trial (the latter because the SD broadcast on Freeview is awful!).

I haven't read everything in this forum yet and I'm sure there are probably better ways that more experienced users are aware of.

1 Like

Well done :+1:

This is exactly the kind of thing I have been looking for. Now TV especially, but also HD streams for certain channels that Freeview only provides in SD (ITV2, 3, 4, Film4, Sky News etc).

I am not using Apple TV. I have a Nvidia Shield Pro and the Deep Links mentioned above don’t seem to work for the Android TV app versions of Now TV, BBC iPlayer, ITVX etc… I have done some digging with the Now TV app and when connected via ADB and running Logcat, I can see nowtv://go/query/service_key/xxxx/play being referenced when playing a live channel.

But, it doesn’t seem to allow direct playback when running it directly. The app opens, but that’s about it.

At first glance, the AndroidManifest.xml seemed to support deep linking through the activity:

<activity android:name="com.sky.clientlib.deeplink.DeeplinkActivity" android:exported="true" android:launchMode="singleInstance" android:screenOrientation="landscape">
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
        <data android:scheme="https" android:host="tv.client.ott.sky.com"/>
    </intent-filter>
</activity>

Would anyone (with a little more knowledge than me!) happen to know if Now TV deep linking for direct stream of live channels is possible on Android TV?

1 Like

Based on what you pasted, it's possible using the URL https://tv.client.ott.sky.com

1 Like

Hey thanks for getting back to me. Yeah, that will launch the app itself, but I’m struggling to figure out how to start a channel stream. It looks like this is possible with the Apple TV version of the app using nowtv://go/query/service_key/xxxx/play but I can’t replicate that with the Android version.

When I connect via ADB and run Logcat while playing a channel, I can see the following:

03-15 23:49:55.606 3699 3713 I ActivityTaskManager: START u0 {act=android.intent.action.VIEW dat=nowtv://go/query/service_key/4077/play flg=0x14000000} from uid 10061

Which seems to confirm that NowTV is using the same deep link format mentioned above. But I can’t seem to get much further with launching that channel directly.

The entire AndroidManifest is as follows. Am I missing anything obvious?

<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="7000001" android:versionName="7.0.1-AndroidTV-GB" android:compileSdkVersion="34" android:compileSdkVersionCodename="14" android:requiredSplitTypes="base__abi,base__density" android:splitTypes="" package="com.bskyb.nowtv.beta" platformBuildVersionCode="34" platformBuildVersionName="14">
    <uses-sdk android:minSdkVersion="22" android:targetSdkVersion="34"/>
    <uses-feature android:name="android.hardware.location" android:required="false"/>
    <uses-feature android:name="android.software.leanback" android:required="true"/>
    <uses-feature android:name="android.hardware.touchscreen" android:required="false"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.WAKE_LOCK"/>
    <uses-permission android:name="com.google.android.gms.permission.AD_ID"/>
    <permission android:name="com.bskyb.nowtv.beta.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" android:protectionLevel="signature"/>
    <uses-permission android:name="com.bskyb.nowtv.beta.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"/>
    <application android:theme="@style/BackgroundStartup" android:label="@string/application_name" android:icon="@mipmap/ic_launcher" android:allowBackup="false" android:supportsRtl="true" android:banner="@mipmap/ic_banner" android:extractNativeLibs="false" android:networkSecurityConfig="@xml/network_security_config" android:appComponentFactory="androidx.core.app.CoreComponentFactory" android:isSplitRequired="true">
        <activity android:name="sky.wrapper.tv.GoogleMainActivity" android:exported="true" android:launchMode="singleTask" android:screenOrientation="landscape" android:configChanges="keyboardHidden">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
                <category android:name="android.intent.category.LEANBACK_LAUNCHER"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>
        <activity android:name="com.sky.clientlib.deeplink.DeeplinkActivity" android:exported="true" android:launchMode="singleInstance" android:screenOrientation="landscape" android:configChanges="keyboardHidden">
            <intent-filter android:autoVerify="true">
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.BROWSABLE"/>
                <data android:scheme="https" android:host="tv.client.ott.sky.com"/>
            </intent-filter>
        </activity>
        <activity android:name="sky.wrapper.tv.ErrorActivity" android:exported="true" android:screenOrientation="landscape" android:configChanges="keyboardHidden">
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
            </intent-filter>
        </activity>
        <service android:name="com.sky.core.player.sdk.downloads.DownloadServiceImpl" android:exported="false">
            <intent-filter>
                <action android:name="com.google.android.exoplayer.downloadService.action.RESTART"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </service>
        <service android:name="androidx.media3.exoplayer.scheduler.PlatformScheduler$PlatformSchedulerService" android:permission="android.permission.BIND_JOB_SERVICE" android:exported="true"/>
        <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>
        <provider android:name="androidx.startup.InitializationProvider" android:exported="false" android:authorities="com.bskyb.nowtv.beta.androidx-startup">
            <meta-data android:name="androidx.emoji2.text.EmojiCompatInitializer" android:value="androidx.startup"/>
            <meta-data android:name="androidx.lifecycle.ProcessLifecycleInitializer" android:value="androidx.startup"/>
            <meta-data android:name="androidx.profileinstaller.ProfileInstallerInitializer" android:value="androidx.startup"/>
        </provider>
        <receiver android:name="androidx.profileinstaller.ProfileInstallReceiver" android:permission="android.permission.DUMP" android:enabled="true" android:exported="true" android:directBootAware="false">
            <intent-filter>
                <action android:name="androidx.profileinstaller.action.INSTALL_PROFILE"/>
            </intent-filter>
            <intent-filter>
                <action android:name="androidx.profileinstaller.action.SKIP_FILE"/>
            </intent-filter>
            <intent-filter>
                <action android:name="androidx.profileinstaller.action.SAVE_PROFILE"/>
            </intent-filter>
            <intent-filter>
                <action android:name="androidx.profileinstaller.action.BENCHMARK_OPERATION"/>
            </intent-filter>
        </receiver>
        <service android:name="androidx.room.MultiInstanceInvalidationService" android:exported="false"/>
        <provider android:name="com.conviva.platforms.android.ProcessLaunchProvider" android:exported="false" android:authorities="com.bskyb.nowtv.beta.ProcessLaunchProvider"/>
        <meta-data android:name="com.android.vending.splits.required" android:value="true"/>
        <meta-data android:name="com.android.stamp.source" android:value="https://play.google.com/store"/>
        <meta-data android:name="com.android.stamp.type" android:value="STAMP_TYPE_DISTRIBUTION_APK"/>
        <meta-data android:name="com.android.vending.splits" android:resource="@xml/splits0"/>
        <meta-data android:name="com.android.vending.derived.apk.id" android:value="3"/>
    </application>
</manifest>