zhuli 4 săptămâni în urmă
părinte
comite
bc39bce720
1 a modificat fișierele cu 138 adăugiri și 1 ștergeri
  1. 138 1
      HBuilderProjects/shareDynamic.html

+ 138 - 1
HBuilderProjects/shareDynamic.html

@@ -769,6 +769,22 @@
 				params.set('imagePath', normalizeMediaUrl(ipMerged) || ipMerged);
 			}
 			/**
+			 * 与 App utils/shareVideoPrecache.js 一致:无 shareVideoCk 时从页面解析首条 https .mp4,写入唤起链接,
+			 * 便于 App 端 downloadFile 预缓存并与 hash 对齐后优先本地播放。
+			 */
+			try {
+				var ckPrev = params.get('shareVideoCk');
+				if (!ckPrev || String(ckPrev).trim() === '') {
+					var pvid = pickFirstHttpsMp4ForShareVideoPrecache();
+					if (pvid) {
+						var hck = hashShareVideoRemoteUrl(pvid);
+						if (hck) {
+							params.set('shareVideoCk', hck);
+						}
+					}
+				}
+			} catch (eShareCk) {}
+			/**
 			 * App 内无分享 H5 写入的 newdetailsList;若沿用浏览器 URL 里的 fromHomeFeed=1,
 			 * 详情会走「首页种子」分支并禁止 recommend,表现为仅一条、下滑无更多作品。
 			 */
@@ -896,6 +912,7 @@
 		}
 
 		function tryOpenHBuilderApp() {
+			prefetchShareVideoBeforeAppOpen();
 			var deepLink = buildAppDeepLink();
 
 			if (typeof plus !== 'undefined' && plus.runtime) {
@@ -1024,7 +1041,8 @@
 			'needShowMore',
 			'fromHomeFeed',
 			'appPath',
-			'appPage'
+			'appPage',
+			'shareVideoCk'
 		];
 
 		function findShareQueryValueStart(q, paramName) {
@@ -1913,6 +1931,125 @@
 			return urls;
 		}
 
+		/** 与 App utils/shareVideoPrecache.js:canonical + hash 一致 */
+		function canonicalVideoUrlForPrecacheKey(url) {
+			var s = String(url == null ? '' : url).trim();
+			if (!s) return '';
+			try {
+				var u = new URL(s);
+				return (u.origin + u.pathname).toLowerCase();
+			} catch (eCan) {
+				return String(s.split('?')[0] || '')
+					.trim()
+					.toLowerCase();
+			}
+		}
+
+		function hashShareVideoRemoteUrl(url) {
+			var c = canonicalVideoUrlForPrecacheKey(url);
+			if (!c) return '';
+			var h = 5381;
+			for (var i = 0; i < c.length; i++) {
+				h = ((h << 5) + h + c.charCodeAt(i)) >>> 0;
+			}
+			var h2 = 52711;
+			for (var j = c.length - 1; j >= 0; j--) {
+				h2 = (h2 * 33 + c.charCodeAt(j)) >>> 0;
+			}
+			return (h >>> 0).toString(16) + '_' + (h2 >>> 0).toString(16) + '_' + c.length;
+		}
+
+		/**
+		 * 唤起 App 前解析首条可播 https .mp4(与详情 DomVideoPlayer 主片同源),供 shareVideoCk 与预取。
+		 */
+		function pickFirstHttpsMp4ForShareVideoPrecache() {
+			var seen = [];
+			function trySeg(u) {
+				u = normalizeMediaUrl(String(u || '').trim());
+				if (!u || seen.indexOf(u) >= 0) return '';
+				seen.push(u);
+				var play = getMp4PlaybackUrl(u);
+				if (!play || !/^https:\/\//i.test(play)) return '';
+				if (!isMp4VideoUrl(play)) return '';
+				return play;
+			}
+			var itemObj = parseOptionsItem();
+			if (itemObj) {
+				if (Array.isArray(itemObj.imageList)) {
+					for (var ii = 0; ii < itemObj.imageList.length; ii++) {
+						var t0 = trySeg(itemObj.imageList[ii]);
+						if (t0) return t0;
+					}
+				}
+				if (itemObj.imagePath) {
+					var ips = String(itemObj.imagePath).split(/,(?=https?:\/\/)/);
+					if (ips.length <= 1) ips = String(itemObj.imagePath).split(',');
+					for (var jj = 0; jj < ips.length; jj++) {
+						var t1 = trySeg(ips[jj]);
+						if (t1) return t1;
+					}
+				}
+			}
+			var itBlob = parseShareDynamicItemBlob();
+			if (itBlob && itBlob !== itemObj) {
+				if (Array.isArray(itBlob.imageList)) {
+					for (var aa = 0; aa < itBlob.imageList.length; aa++) {
+						var t2 = trySeg(itBlob.imageList[aa]);
+						if (t2) return t2;
+					}
+				}
+				if (itBlob.imagePath) {
+					var ips2 = String(itBlob.imagePath).split(/,(?=https?:\/\/)/);
+					if (ips2.length <= 1) ips2 = String(itBlob.imagePath).split(',');
+					for (var bb = 0; bb < ips2.length; bb++) {
+						var t3 = trySeg(ips2[bb]);
+						if (t3) return t3;
+					}
+				}
+			}
+			var carousel = collectImageUrlsFromUrl();
+			for (var kk = 0; kk < carousel.length; kk++) {
+				var t4 = trySeg(carousel[kk]);
+				if (t4) return t4;
+			}
+			var topIp = getMergedParam('imagePath');
+			if (topIp) {
+				var segs2 = normalizeMediaUrl(topIp).split(/,(?=https?:\/\/)/);
+				if (segs2.length <= 1) segs2 = String(topIp).split(',');
+				for (var mm = 0; mm < segs2.length; mm++) {
+					var t5 = trySeg(segs2[mm]);
+					if (t5) return t5;
+				}
+			}
+			return '';
+		}
+
+		/** 唤醒 App 前尽力拉取视频(Cache API / prefetch / fetch);与 App 沙箱缓存独立,仅减轻部分环境下的首包 */
+		function prefetchShareVideoBeforeAppOpen() {
+			try {
+				var u = pickFirstHttpsMp4ForShareVideoPrecache();
+				if (!u) return;
+				if ('caches' in window && window.caches && window.caches.open) {
+					window.caches
+						.open('shopro-share-dynamic-video-v1')
+						.then(function (cache) {
+							return cache.add(u);
+						})
+						.catch(function () {});
+				}
+				try {
+					var lnk = document.createElement('link');
+					lnk.rel = 'prefetch';
+					lnk.as = 'video';
+					lnk.href = u;
+					document.head.appendChild(lnk);
+				} catch (eL) {}
+				if (typeof fetch === 'function') {
+					fetch(u, { method: 'GET', mode: 'cors', cache: 'force-cache' }).catch(function () {});
+				}
+			} catch (eP) {}
+		}
+
 		var heroI = 0;
 		var heroTimer = null;
 		var dynHeroSwipeInited = false;