diff --git a/app/src/main/java/com/futo/platformplayer/Extensions_Formatting.kt b/app/src/main/java/com/futo/platformplayer/Extensions_Formatting.kt
index 5776d3812679a333042557b06dd5c14e34d30e6d..6c316ac5021a08fb6189e7b05ec8f8929d2b803a 100644
--- a/app/src/main/java/com/futo/platformplayer/Extensions_Formatting.kt
+++ b/app/src/main/java/com/futo/platformplayer/Extensions_Formatting.kt
@@ -13,6 +13,8 @@ import java.text.DecimalFormat
 import java.time.OffsetDateTime
 import java.time.temporal.ChronoUnit
 import kotlin.math.abs
+import kotlin.math.roundToInt
+import kotlin.math.roundToLong
 
 
 //Long
@@ -119,7 +121,8 @@ fun OffsetDateTime.getNowDiffMonths(): Long {
     return ChronoUnit.MONTHS.between(this, OffsetDateTime.now());
 }
 fun OffsetDateTime.getNowDiffYears(): Long {
-    return ChronoUnit.YEARS.between(this, OffsetDateTime.now());
+    val diff = ChronoUnit.MONTHS.between(this, OffsetDateTime.now()) / 12.0;
+    return diff.roundToLong();
 }
 
 fun OffsetDateTime.getDiffDays(otherDate: OffsetDateTime): Long {
@@ -150,6 +153,7 @@ fun OffsetDateTime.toHumanNowDiffString(abs: Boolean = false) : String {
     if(value >= secondsInYear) {
         value = getNowDiffYears();
         if(abs) value = abs(value);
+        value = Math.max(1, value);
         unit = "year";
     }
     else if(value >= secondsInMonth) {
diff --git a/app/src/main/java/com/futo/platformplayer/UIDialogs.kt b/app/src/main/java/com/futo/platformplayer/UIDialogs.kt
index f0b8abeabc14f7efc839afad6cb051693d583845..ec6664622a5f52068d0f95be15d892a5137cffc2 100644
--- a/app/src/main/java/com/futo/platformplayer/UIDialogs.kt
+++ b/app/src/main/java/com/futo/platformplayer/UIDialogs.kt
@@ -34,6 +34,7 @@ import com.futo.platformplayer.dialogs.MigrateDialog
 import com.futo.platformplayer.dialogs.ProgressDialog
 import com.futo.platformplayer.engine.exceptions.PluginException
 import com.futo.platformplayer.logging.Logger
+import com.futo.platformplayer.models.ImportCache
 import com.futo.platformplayer.states.StateApp
 import com.futo.platformplayer.states.StateBackup
 import com.futo.platformplayer.stores.v2.ManagedStore
@@ -343,8 +344,8 @@ class UIDialogs {
             }
         }
 
-        fun showImportDialog(context: Context, store: ManagedStore<*>, name: String, reconstructions: List<String>, onConcluded: () -> Unit) {
-            val dialog = ImportDialog(context, store, name, reconstructions, onConcluded);
+        fun showImportDialog(context: Context, store: ManagedStore<*>, name: String, reconstructions: List<String>, cache: ImportCache?, onConcluded: () -> Unit) {
+            val dialog = ImportDialog(context, store, name, reconstructions, cache, onConcluded);
             registerDialogOpened(dialog);
             dialog.setOnDismissListener { registerDialogClosed(dialog) };
             dialog.show();
diff --git a/app/src/main/java/com/futo/platformplayer/activities/MainActivity.kt b/app/src/main/java/com/futo/platformplayer/activities/MainActivity.kt
index 3ba926767718451147e46cfed392911099f8bd02..9c921982cca0ddd7d0bc0ad629b2f8873896b27b 100644
--- a/app/src/main/java/com/futo/platformplayer/activities/MainActivity.kt
+++ b/app/src/main/java/com/futo/platformplayer/activities/MainActivity.kt
@@ -41,6 +41,7 @@ import com.futo.platformplayer.fragment.mainactivity.topbar.NavigationTopBarFrag
 import com.futo.platformplayer.fragment.mainactivity.topbar.SearchTopBarFragment
 import com.futo.platformplayer.listeners.OrientationManager
 import com.futo.platformplayer.logging.Logger
+import com.futo.platformplayer.models.ImportCache
 import com.futo.platformplayer.models.UrlVideoWithTime
 import com.futo.platformplayer.states.*
 import com.futo.platformplayer.stores.FragmentedStorage
@@ -603,7 +604,7 @@ class MainActivity : AppCompatActivity, IWithResultLauncher {
                     UIDialogs.showSingleButtonDialog(
                         this,
                         R.drawable.ic_play,
-                        getString(R.string.unknown_content_format) + " [${url}]",
+                        getString(R.string.unknown_content_format) + " [${url}]\n[${intent.type}]",
                         "Ok",
                         { });
                 }
@@ -693,10 +694,22 @@ class MainActivity : AppCompatActivity, IWithResultLauncher {
             if(!recon.trim().startsWith("["))
                 return handleUnknownJson(recon);
 
-            val reconLines = Json.decodeFromString<List<String>>(recon);
+            var reconLines = Json.decodeFromString<List<String>>(recon);
+            val cacheStr = reconLines.find { it.startsWith("__CACHE:") }?.substring("__CACHE:".length);
+            reconLines = reconLines.filter { !it.startsWith("__CACHE:") }; //TODO: constant prefix
+            var cache: ImportCache? = null;
+            try {
+                if(cacheStr != null)
+                    cache = Json.decodeFromString(cacheStr);
+            }
+            catch(ex: Throwable) {
+                Logger.e(TAG, "Failed to deserialize cache");
+            }
+
+
             recon = reconLines.joinToString("\n");
             Logger.i(TAG, "Opened shared playlist reconstruction\n${recon}");
-            handleReconstruction(recon);
+            handleReconstruction(recon, cache);
             return true;
         }
         else if(file.lowercase().endsWith(".zip") || mime == "application/zip") {
@@ -711,12 +724,25 @@ class MainActivity : AppCompatActivity, IWithResultLauncher {
     fun handleFile(file: String): Boolean {
         Logger.i(TAG, "handleFile(url=$file)");
         if(file.lowercase().endsWith(".json")) {
-            val recon = String(readSharedFile(file));
+            var recon = String(readSharedFile(file));
             if(!recon.startsWith("["))
                 return handleUnknownJson(recon);
 
+            var reconLines = Json.decodeFromString<List<String>>(recon);
+            val cacheStr = reconLines.find { it.startsWith("__CACHE:") }?.substring("__CACHE:".length);
+            reconLines = reconLines.filter { !it.startsWith("__CACHE:") }; //TODO: constant prefix
+            var cache: ImportCache? = null;
+            try {
+                if(cacheStr != null)
+                    cache = Json.decodeFromString(cacheStr);
+            }
+            catch(ex: Throwable) {
+                Logger.e(TAG, "Failed to deserialize cache");
+            }
+            recon = reconLines.joinToString("\n");
+
             Logger.i(TAG, "Opened shared playlist reconstruction\n${recon}");
-            handleReconstruction(recon);
+            handleReconstruction(recon, cache);
             return true;
         }
         else if(file.lowercase().endsWith(".zip")) {
@@ -728,7 +754,7 @@ class MainActivity : AppCompatActivity, IWithResultLauncher {
         }
         return false;
     }
-    fun handleReconstruction(recon: String) {
+    fun handleReconstruction(recon: String, cache: ImportCache? = null) {
         val type = ManagedStore.getReconstructionIdentifier(recon);
         val store: ManagedStore<*> = when(type) {
             "Playlist" -> StatePlaylists.instance.playlistStore
@@ -745,7 +771,7 @@ class MainActivity : AppCompatActivity, IWithResultLauncher {
 
 
         if(!type.isNullOrEmpty()) {
-            UIDialogs.showImportDialog(this, store, name, listOf(recon)) {
+            UIDialogs.showImportDialog(this, store, name, listOf(recon), cache) {
 
             }
         }
diff --git a/app/src/main/java/com/futo/platformplayer/api/media/models/channels/SerializedChannel.kt b/app/src/main/java/com/futo/platformplayer/api/media/models/channels/SerializedChannel.kt
index 7c457a30464c1ddbb70ab40b8ec6c7991cbf01e9..50c53f9c8c40cce62925125bbc7d00dfccd1960d 100644
--- a/app/src/main/java/com/futo/platformplayer/api/media/models/channels/SerializedChannel.kt
+++ b/app/src/main/java/com/futo/platformplayer/api/media/models/channels/SerializedChannel.kt
@@ -37,6 +37,10 @@ class SerializedChannel(
         TODO("Not yet implemented")
     }
 
+    fun isSameUrl(url: String): Boolean {
+        return this.url == url || urlAlternatives.contains(url);
+    }
+
     companion object {
         fun fromChannel(channel: IPlatformChannel): SerializedChannel {
             return SerializedChannel(
diff --git a/app/src/main/java/com/futo/platformplayer/dialogs/ImportDialog.kt b/app/src/main/java/com/futo/platformplayer/dialogs/ImportDialog.kt
index 76c15ae92f9e446c153fe563b4eff522820c6f70..c7d66ae1f58d2cad5db8a34ad9a5a042b2a315c5 100644
--- a/app/src/main/java/com/futo/platformplayer/dialogs/ImportDialog.kt
+++ b/app/src/main/java/com/futo/platformplayer/dialogs/ImportDialog.kt
@@ -22,7 +22,9 @@ import com.futo.platformplayer.UIDialogs
 import com.futo.platformplayer.api.media.exceptions.NoPlatformClientException
 import com.futo.platformplayer.assume
 import com.futo.platformplayer.logging.Logger
+import com.futo.platformplayer.models.ImportCache
 import com.futo.platformplayer.states.StateApp
+import com.futo.platformplayer.states.StateBackup
 import com.futo.platformplayer.stores.v2.ManagedStore
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -66,13 +68,15 @@ class ImportDialog : AlertDialog {
     private val _name: String;
     private val _toImport: List<String>;
 
+    private val _cache: ImportCache?;
 
-    constructor(context: Context, importStore: ManagedStore<*>, name: String, toReconstruct: List<String>, onConcluded: ()->Unit): super(context) {
+    constructor(context: Context, importStore: ManagedStore<*>, name: String, toReconstruct: List<String>, cache: ImportCache?, onConcluded: ()->Unit): super(context) {
         _context = context;
         _store = importStore;
         _onConcluded = onConcluded;
         _name = name;
         _toImport = ArrayList(toReconstruct);
+        _cache = cache;
     }
 
     override fun onCreate(savedInstanceState: Bundle?) {
@@ -146,7 +150,7 @@ class ImportDialog : AlertDialog {
         val scope = StateApp.instance.scopeOrNull;
         scope?.launch(Dispatchers.IO) {
             try {
-                val migrationResult = _store.importReconstructions(_toImport) { finished, total ->
+                val migrationResult = _store.importReconstructions(_toImport, _cache) { finished, total ->
                     scope.launch(Dispatchers.Main) {
                         _textProgress.text = "${finished}/${total}";
                     }
diff --git a/app/src/main/java/com/futo/platformplayer/models/HistoryVideo.kt b/app/src/main/java/com/futo/platformplayer/models/HistoryVideo.kt
index a05fadc786ccced83a4138ef7754a85897344a98..b491f95fc113f0462b1b0266f9c244306457873d 100644
--- a/app/src/main/java/com/futo/platformplayer/models/HistoryVideo.kt
+++ b/app/src/main/java/com/futo/platformplayer/models/HistoryVideo.kt
@@ -30,7 +30,7 @@ class HistoryVideo {
     }
 
     companion object {
-        fun fromReconString(str: String, resolve: ((url: String)->SerializedPlatformVideo)? = null): HistoryVideo {
+        fun fromReconString(str: String, resolve: ((url: String)->SerializedPlatformVideo?)? = null): HistoryVideo {
             var index = str.indexOf("|||");
             if(index < 0) throw IllegalArgumentException("Invalid history string: " + str);
             val url = str.substring(0, index);
diff --git a/app/src/main/java/com/futo/platformplayer/models/ImportCache.kt b/app/src/main/java/com/futo/platformplayer/models/ImportCache.kt
new file mode 100644
index 0000000000000000000000000000000000000000..6462edc0dc0e8b33d312ee9afcffcc09be732fac
--- /dev/null
+++ b/app/src/main/java/com/futo/platformplayer/models/ImportCache.kt
@@ -0,0 +1,11 @@
+package com.futo.platformplayer.models
+
+import com.futo.platformplayer.api.media.models.channels.SerializedChannel
+import com.futo.platformplayer.api.media.models.video.SerializedPlatformVideo
+import kotlinx.serialization.Serializable
+
+@Serializable
+class ImportCache(
+    var videos: List<SerializedPlatformVideo>? = null,
+    var channels: List<SerializedChannel>? = null
+);
\ No newline at end of file
diff --git a/app/src/main/java/com/futo/platformplayer/states/StateBackup.kt b/app/src/main/java/com/futo/platformplayer/states/StateBackup.kt
index 35bb14ce1fb5f53aefc42b4859ba5f0c524b9b5e..bd428c6d89e629fe59d0072f85104cd7be36c68a 100644
--- a/app/src/main/java/com/futo/platformplayer/states/StateBackup.kt
+++ b/app/src/main/java/com/futo/platformplayer/states/StateBackup.kt
@@ -10,6 +10,7 @@ import com.futo.platformplayer.UIDialogs
 import com.futo.platformplayer.activities.IWithResultLauncher
 import com.futo.platformplayer.activities.MainActivity
 import com.futo.platformplayer.activities.SettingsActivity
+import com.futo.platformplayer.api.media.models.channels.SerializedChannel
 import com.futo.platformplayer.api.media.models.video.SerializedPlatformVideo
 import com.futo.platformplayer.copyTo
 import com.futo.platformplayer.encryption.GPasswordEncryptionProvider
@@ -17,6 +18,7 @@ import com.futo.platformplayer.encryption.GPasswordEncryptionProviderV0
 import com.futo.platformplayer.fragment.mainactivity.main.ImportSubscriptionsFragment
 import com.futo.platformplayer.getNowDiffHours
 import com.futo.platformplayer.logging.Logger
+import com.futo.platformplayer.models.ImportCache
 import com.futo.platformplayer.readBytes
 import com.futo.platformplayer.stores.FragmentedStorage
 import com.futo.platformplayer.stores.v2.ManagedStore
@@ -58,6 +60,19 @@ class StateBackup {
             StatePlaylists.instance.toMigrateCheck()
         ).flatten();
 
+        fun getCache(): ImportCache {
+            val allPlaylists = StatePlaylists.instance.getPlaylists();
+            val videos = allPlaylists.flatMap { it.videos }.distinctBy { it.url };
+
+            val allSubscriptions = StateSubscriptions.instance.getSubscriptions();
+            val channels = allSubscriptions.map { it.channel };
+
+            return ImportCache(
+                videos = videos,
+                channels = channels
+            );
+        }
+
 
         private fun getAutomaticBackupPassword(customPassword: String? = null): String {
             val password = customPassword ?: Settings.instance.backup.autoBackupPassword ?: "";
@@ -233,11 +248,10 @@ class StateBackup {
                 .associateBy { it.config.id }
                 .mapValues { it.value.config.sourceUrl!! };
 
+            val cache = getCache();
+
+            val export = ExportStructure(exportInfo, settings, storesToSave, pluginUrls, pluginSettings, cache);
 
-            val export = ExportStructure(exportInfo, settings, storesToSave, pluginUrls, pluginSettings);
-            //export.videoCache = StatePlaylists.instance.getHistory()
-            //    .distinctBy { it.video.url }
-            //    .map { it.video };
             return export;
         }
 
@@ -324,7 +338,7 @@ class StateBackup {
                                             continue;
                                         }
                                         withContext(Dispatchers.Main) {
-                                            UIDialogs.showImportDialog(context, relevantStore, store.key, store.value) {
+                                            UIDialogs.showImportDialog(context, relevantStore, store.key, store.value, export.cache) {
                                                 synchronized(toAwait) {
                                                     toAwait.remove(store.key);
                                                     if(toAwait.isEmpty())
@@ -453,8 +467,8 @@ class StateBackup {
         val stores: Map<String, List<String>>,
         val plugins: Map<String, String>,
         val pluginSettings: Map<String, Map<String, String?>>,
+        var cache: ImportCache? = null
     ) {
-        var videoCache: List<SerializedPlatformVideo>? = null;
 
         fun asZip(): ByteArray {
             return ByteArrayOutputStream().use { byteStream ->
@@ -478,6 +492,17 @@ class StateBackup {
 
                     zipStream.putNextEntry(ZipEntry("plugin_settings"));
                     zipStream.write(Json.encodeToString(pluginSettings).toByteArray());
+
+                    if(cache != null) {
+                        if(cache?.videos != null) {
+                            zipStream.putNextEntry(ZipEntry("cache_videos"));
+                            zipStream.write(Json.encodeToString(cache!!.videos).toByteArray());
+                        }
+                        if(cache?.channels != null) {
+                            zipStream.putNextEntry(ZipEntry("cache_channels"));
+                            zipStream.write(Json.encodeToString(cache!!.channels).toByteArray());
+                        }
+                    }
                 };
                 return byteStream.toByteArray();
             }
@@ -492,6 +517,8 @@ class StateBackup {
                 val stores: MutableMap<String, List<String>> = mutableMapOf();
                 var plugins: Map<String, String> = mapOf();
                 var pluginSettings: Map<String, Map<String, String?>> = mapOf();
+                var videoCache: List<SerializedPlatformVideo>? = null
+                var channelCache: List<SerializedChannel>? = null
 
                 while (zipStream.nextEntry.also { entry = it } != null) {
                     if(entry!!.isDirectory)
@@ -503,6 +530,22 @@ class StateBackup {
                                 "settings" -> settings = String(zipStream.readBytes());
                                 "plugins" -> plugins = Json.decodeFromString(String(zipStream.readBytes()));
                                 "plugin_settings" -> pluginSettings = Json.decodeFromString(String(zipStream.readBytes()));
+                                "cache_videos" -> {
+                                    try {
+                                        videoCache = Json.decodeFromString(String(zipStream.readBytes()));
+                                    }
+                                    catch(ex: Exception) {
+                                        Logger.e(TAG, "Couldn't deserialize video cache", ex);
+                                    }
+                                };
+                                "cache_channels" -> {
+                                    try {
+                                        channelCache = Json.decodeFromString(String(zipStream.readBytes()));
+                                    }
+                                    catch(ex: Exception) {
+                                        Logger.e(TAG, "Couldn't deserialize channel cache", ex);
+                                    }
+                                };
                             }
                         else
                             stores[entry!!.name.substring("stores/".length)] = Json.decodeFromString(String(zipStream.readBytes()));
@@ -511,7 +554,10 @@ class StateBackup {
                         throw IllegalStateException("Failed to parse zip [${entry?.name}] due to ${ex.message}");
                     }
                 }
-                return ExportStructure(exportInfo, settings, stores, plugins, pluginSettings);
+                return ExportStructure(exportInfo, settings, stores, plugins, pluginSettings, ImportCache(
+                    videos = videoCache,
+                    channels = channelCache
+                ));
             }
         }
     }
diff --git a/app/src/main/java/com/futo/platformplayer/states/StateHistory.kt b/app/src/main/java/com/futo/platformplayer/states/StateHistory.kt
index d61b8ab303399e3ad5945ffebfcef08aaeaaf473..4499ceda0910db7a4ec04d21b8e9872d87689d66 100644
--- a/app/src/main/java/com/futo/platformplayer/states/StateHistory.kt
+++ b/app/src/main/java/com/futo/platformplayer/states/StateHistory.kt
@@ -7,6 +7,7 @@ import com.futo.platformplayer.api.media.structures.IPager
 import com.futo.platformplayer.constructs.Event2
 import com.futo.platformplayer.logging.Logger
 import com.futo.platformplayer.models.HistoryVideo
+import com.futo.platformplayer.models.ImportCache
 import com.futo.platformplayer.stores.FragmentedStorage
 import com.futo.platformplayer.stores.db.ManagedDBStore
 import com.futo.platformplayer.stores.db.types.DBHistory
@@ -20,8 +21,8 @@ class StateHistory {
     private val _historyStore = FragmentedStorage.storeJson<HistoryVideo>("history")
         .withRestore(object: ReconstructStore<HistoryVideo>() {
             override fun toReconstruction(obj: HistoryVideo): String = obj.toReconString();
-            override suspend fun toObject(id: String, backup: String, reconstructionBuilder: Builder): HistoryVideo
-                    = HistoryVideo.fromReconString(backup, null);
+            override suspend fun toObject(id: String, backup: String, reconstructionBuilder: Builder, cache: ImportCache?): HistoryVideo
+                    = HistoryVideo.fromReconString(backup) { url -> cache?.videos?.find { it.url == url } };
         })
         .load();
 
diff --git a/app/src/main/java/com/futo/platformplayer/states/StatePlaylists.kt b/app/src/main/java/com/futo/platformplayer/states/StatePlaylists.kt
index 008a5d1c280b0f519e33abd8cafcd1b8f062cd4f..84b6eb517697164f9e710de8f0832fdc525e798d 100644
--- a/app/src/main/java/com/futo/platformplayer/states/StatePlaylists.kt
+++ b/app/src/main/java/com/futo/platformplayer/states/StatePlaylists.kt
@@ -14,6 +14,7 @@ import com.futo.platformplayer.constructs.Event0
 import com.futo.platformplayer.engine.exceptions.ScriptUnavailableException
 import com.futo.platformplayer.exceptions.ReconstructionException
 import com.futo.platformplayer.logging.Logger
+import com.futo.platformplayer.models.ImportCache
 import com.futo.platformplayer.models.Playlist
 import com.futo.platformplayer.stores.FragmentedStorage
 import com.futo.platformplayer.stores.StringArrayStorage
@@ -32,8 +33,10 @@ class StatePlaylists {
         .withUnique { it.url }
         .withRestore(object: ReconstructStore<SerializedPlatformVideo>() {
             override fun toReconstruction(obj: SerializedPlatformVideo): String = obj.url;
-            override suspend fun toObject(id: String, backup: String, reconstructionBuilder: Builder): SerializedPlatformVideo
-                = SerializedPlatformVideo.fromVideo(StatePlatform.instance.getContentDetails(backup).await() as IPlatformVideoDetails);
+            override suspend fun toObject(id: String, backup: String, reconstructionBuilder: Builder, importCache: ImportCache?): SerializedPlatformVideo
+                = SerializedPlatformVideo.fromVideo(
+                    importCache?.videos?.find { it.url == backup }?.let { Logger.i(TAG, "Reconstruction [${backup}] from cache"); return@let it; } ?:
+                    StatePlatform.instance.getContentDetails(backup).await() as IPlatformVideoDetails);
         })
         .load();
     private val _watchlistOrderStore = FragmentedStorage.get<StringArrayStorage>("watchListOrder"); //Temporary workaround to add order..
@@ -154,7 +157,11 @@ class StatePlaylists {
         val reconstruction = playlistStore.getReconstructionString(playlist, true);
 
         val newFile = File(playlistShareDir, playlist.name + ".json");
-        newFile.writeText(Json.encodeToString(reconstruction.split("\n")), Charsets.UTF_8);
+        newFile.writeText(Json.encodeToString(reconstruction.split("\n") + listOf(
+            "__CACHE:" + Json.encodeToString(ImportCache(
+                videos = playlist.videos.toList()
+            ))
+        )), Charsets.UTF_8);
 
         return FileProvider.getUriForFile(context, context.resources.getString(R.string.authority), newFile);
     }
@@ -185,7 +192,7 @@ class StatePlaylists {
             items.addAll(obj.videos.map { it.url });
             return items.map { it.replace("\n","") }.joinToString("\n");
         }
-        override suspend fun toObject(id: String, backup: String, reconstructionBuilder: Builder): Playlist {
+        override suspend fun toObject(id: String, backup: String, reconstructionBuilder: Builder, importCache: ImportCache?): Playlist {
             val items = backup.split("\n");
             if(items.size <= 0) {
                 throw IllegalStateException("Cannot reconstructor playlist ${id}");
@@ -194,10 +201,17 @@ class StatePlaylists {
             val name = items[0];
             val videos = items.drop(1).filter { it.isNotEmpty() }.map {
                 try {
-                    val video = StatePlatform.instance.getContentDetails(it).await();
+                    val videoUrl = it;
+                    val video = importCache?.videos?.find { it.url == videoUrl } ?:
+                        StatePlatform.instance.getContentDetails(it).await();
                     if (video is IPlatformVideoDetails) {
                         return@map SerializedPlatformVideo.fromVideo(video);
-                    } else {
+                    }
+                    else if(video is SerializedPlatformVideo) {
+                        Logger.i(TAG, "Reconstruction [${it}] from cache");
+                        return@map video;
+                    }
+                    else {
                         return@map null
                     }
                 }
diff --git a/app/src/main/java/com/futo/platformplayer/states/StateSubscriptions.kt b/app/src/main/java/com/futo/platformplayer/states/StateSubscriptions.kt
index 4f2e60c1e711561fde6d2f7e4c35325212605e33..da54578dd8549eccf40230b293634b2b66c587b1 100644
--- a/app/src/main/java/com/futo/platformplayer/states/StateSubscriptions.kt
+++ b/app/src/main/java/com/futo/platformplayer/states/StateSubscriptions.kt
@@ -12,6 +12,7 @@ import com.futo.platformplayer.constructs.Event2
 import com.futo.platformplayer.constructs.Event3
 import com.futo.platformplayer.functional.CentralizedFeed
 import com.futo.platformplayer.logging.Logger
+import com.futo.platformplayer.models.ImportCache
 import com.futo.platformplayer.models.Subscription
 import com.futo.platformplayer.models.SubscriptionGroup
 import com.futo.platformplayer.polycentric.PolycentricCache
@@ -38,8 +39,8 @@ class StateSubscriptions {
         .withRestore(object: ReconstructStore<Subscription>(){
             override fun toReconstruction(obj: Subscription): String =
                 obj.channel.url;
-            override suspend fun toObject(id: String, backup: String, reconstructionBuilder: Builder): Subscription =
-                Subscription(SerializedChannel.fromChannel(StatePlatform.instance.getChannelLive(backup, false)));
+            override suspend fun toObject(id: String, backup: String, reconstructionBuilder: Builder, importCache: ImportCache?): Subscription =
+                Subscription(importCache?.channels?.find { it.isSameUrl(backup) } ?: SerializedChannel.fromChannel(StatePlatform.instance.getChannelLive(backup, false)));
         }).load();
     private val _subscriptionOthers = FragmentedStorage.storeJson<Subscription>("subscriptions_others")
         .withUnique { it.channel.url }
diff --git a/app/src/main/java/com/futo/platformplayer/stores/v2/ManagedStore.kt b/app/src/main/java/com/futo/platformplayer/stores/v2/ManagedStore.kt
index ec0a9fa2279fb821f16ddfd470df1f2982009ffa..9673348401c241c4cfc65052a4dcc92e8043cf7a 100644
--- a/app/src/main/java/com/futo/platformplayer/stores/v2/ManagedStore.kt
+++ b/app/src/main/java/com/futo/platformplayer/stores/v2/ManagedStore.kt
@@ -2,6 +2,7 @@ package com.futo.platformplayer.stores.v2
 
 import com.futo.platformplayer.assume
 import com.futo.platformplayer.logging.Logger
+import com.futo.platformplayer.models.ImportCache
 import com.futo.platformplayer.states.StateApp
 import kotlinx.coroutines.Dispatchers
 import kotlinx.coroutines.launch
@@ -105,7 +106,7 @@ class ManagedStore<T>{
             _toReconstruct.clear();
         }
     }
-    suspend fun importReconstructions(items: List<String>, onProgress: ((Int, Int)->Unit)? = null): ReconstructionResult {
+    suspend fun importReconstructions(items: List<String>, cache: ImportCache? = null, onProgress: ((Int, Int)->Unit)? = null): ReconstructionResult {
         var successes = 0;
         val exs = ArrayList<Throwable>();
 
@@ -120,7 +121,7 @@ class ManagedStore<T>{
             for (i in 0 .. 1) {
                 try {
                     Logger.i(TAG, "Importing ${logName(recon)}");
-                    val reconId = createFromReconstruction(recon, builder);
+                    val reconId = createFromReconstruction(recon, builder, cache);
                     successes++;
                     Logger.i(TAG, "Imported ${logName(reconId)}");
                     break;
@@ -272,12 +273,12 @@ class ManagedStore<T>{
             save(obj, withReconstruction, onlyExisting);
     }
 
-    suspend fun createFromReconstruction(reconstruction: String, builder: ReconstructStore.Builder): String {
+    suspend fun createFromReconstruction(reconstruction: String, builder: ReconstructStore.Builder, cache: ImportCache? = null): String {
         if(_reconstructStore == null)
             throw IllegalStateException("Can't reconstruct as no reconstruction is implemented for this type");
 
         val id = UUID.randomUUID().toString();
-        val reconstruct = _reconstructStore!!.toObjectWithHeader(id, reconstruction, builder);
+        val reconstruct = _reconstructStore!!.toObjectWithHeader(id, reconstruction, builder, cache);
         save(reconstruct);
         return id;
     }
diff --git a/app/src/main/java/com/futo/platformplayer/stores/v2/ReconstructStore.kt b/app/src/main/java/com/futo/platformplayer/stores/v2/ReconstructStore.kt
index 78004a297c8af059f0ba844e1a6d1eeedb4518ae..9e5edf1338fd2fbfd7fbb4adaf9819088cbf39a1 100644
--- a/app/src/main/java/com/futo/platformplayer/stores/v2/ReconstructStore.kt
+++ b/app/src/main/java/com/futo/platformplayer/stores/v2/ReconstructStore.kt
@@ -1,5 +1,7 @@
 package com.futo.platformplayer.stores.v2
 
+import com.futo.platformplayer.models.ImportCache
+
 abstract class ReconstructStore<T> {
     open val backupOnSave: Boolean = false;
     open val backupOnCreate: Boolean = true;
@@ -11,18 +13,18 @@ abstract class ReconstructStore<T> {
     }
 
     abstract fun toReconstruction(obj: T): String;
-    abstract suspend fun toObject(id: String, backup: String, reconstructionBuilder: Builder): T;
+    abstract suspend fun toObject(id: String, backup: String, reconstructionBuilder: Builder, importCache: ImportCache? = null): T;
 
     fun toReconstructionWithHeader(obj: T, fallbackName: String): String {
         val identifier = identifierName ?: fallbackName;
         return "@/${identifier}\n${toReconstruction(obj)}";
     }
 
-    suspend fun toObjectWithHeader(id: String, backup: String, builder: Builder): T {
+    suspend fun toObjectWithHeader(id: String, backup: String, builder: Builder, importCache: ImportCache? = null): T {
         if(backup.startsWith("@/") && backup.contains("\n"))
-            return toObject(id, backup.substring(backup.indexOf("\n") + 1), builder);
+            return toObject(id, backup.substring(backup.indexOf("\n") + 1), builder, importCache);
         else
-            return toObject(id, backup, builder);
+            return toObject(id, backup, builder, importCache);
     }
 
 
diff --git a/app/src/stable/assets/sources/youtube b/app/src/stable/assets/sources/youtube
index 83cccf8ba5ae87d8a437775d9b341a9e3be07e74..bef199baa9df5cb3192c7a3f8baf8c57e9fbdaea 160000
--- a/app/src/stable/assets/sources/youtube
+++ b/app/src/stable/assets/sources/youtube
@@ -1 +1 @@
-Subproject commit 83cccf8ba5ae87d8a437775d9b341a9e3be07e74
+Subproject commit bef199baa9df5cb3192c7a3f8baf8c57e9fbdaea
diff --git a/app/src/unstable/assets/sources/youtube b/app/src/unstable/assets/sources/youtube
index 83cccf8ba5ae87d8a437775d9b341a9e3be07e74..bef199baa9df5cb3192c7a3f8baf8c57e9fbdaea 160000
--- a/app/src/unstable/assets/sources/youtube
+++ b/app/src/unstable/assets/sources/youtube
@@ -1 +1 @@
-Subproject commit 83cccf8ba5ae87d8a437775d9b341a9e3be07e74
+Subproject commit bef199baa9df5cb3192c7a3f8baf8c57e9fbdaea