File indexing completed on 2025-02-02 04:47:49
0001 /* 0002 * SPDX-FileCopyrightText: 2020 Soul Trace <S-trace@list.ru> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL 0005 */ 0006 0007 package org.kde.kdeconnect.Helpers; 0008 0009 import org.apache.commons.lang3.StringUtils; 0010 0011 import java.net.MalformedURLException; 0012 import java.net.URL; 0013 import java.util.Locale; 0014 0015 public class VideoUrlsHelper { 0016 private static final int SECONDS_IN_MINUTE = 60; 0017 private static final int MINUTES_IN_HOUR = 60; 0018 private static final int SECONDS_IN_HOUR = SECONDS_IN_MINUTE * MINUTES_IN_HOUR; 0019 0020 public static URL formatUriWithSeek(String address, long position) 0021 throws MalformedURLException { 0022 URL url = new URL(address); 0023 position /= 1000; // Convert ms to seconds 0024 if (position <= 0) { 0025 return url; // nothing to do 0026 } 0027 String host = url.getHost().toLowerCase(); 0028 0029 // Most common settings as defaults: 0030 String parameter = "t="; // Characters before timestamp 0031 String timestamp = Long.toString(position); // Timestamp itself 0032 String trailer = ""; // Characters after timestamp 0033 // true - search/add to query URL part (between ? and # signs), 0034 // false - search/add timestamp to ref (anchor) URL part (after # sign), 0035 boolean inQuery = true; 0036 // true - We know how to format URL with seek timestamp, false - not 0037 boolean seekUrl = false; 0038 0039 // Override defaults if necessary 0040 if (StringUtils.containsAny(host, "youtube.com", "youtu.be", "pornhub.com")) { 0041 seekUrl = true; 0042 url = stripTimestampS(url, parameter, trailer, inQuery); 0043 } else if (host.contains("vimeo.com")) { 0044 seekUrl = true; 0045 trailer = "s"; 0046 url = stripTimestampS(url, parameter, trailer, inQuery); 0047 } else if (host.contains("dailymotion.com")) { 0048 seekUrl = true; 0049 parameter = "start="; 0050 url = stripTimestampS(url, parameter, trailer, inQuery); 0051 } else if (host.contains("twitch.tv")) { 0052 seekUrl = true; 0053 timestamp = formatTimestampHMS(position, true); 0054 url = stripTimestampHMS(url, parameter, trailer, inQuery); 0055 } 0056 0057 if (seekUrl) { 0058 url = formatUrlWithSeek(url, timestamp, parameter, trailer, inQuery); 0059 } 0060 return url; 0061 } 0062 0063 // Returns timestamp in 1h2m34s or 01h02m34s (according to padWithZeroes) 0064 private static String formatTimestampHMS(long seconds, boolean padWithZeroes) { 0065 if (seconds == 0) { 0066 return "0s"; 0067 } 0068 0069 int sec = (int) (seconds % SECONDS_IN_MINUTE); 0070 int min = (int) ((seconds / SECONDS_IN_MINUTE) % MINUTES_IN_HOUR); 0071 int hour = (int) (seconds / SECONDS_IN_HOUR); 0072 0073 String hours = hour > 0 ? hour + "h" : ""; 0074 String mins = min > 0 || hour > 0 ? min + "m" : ""; 0075 String secs = sec + "s"; 0076 0077 String value; 0078 if (padWithZeroes) { 0079 String hoursPad = hour > 9 ? "" : "0"; 0080 String minsPad = min > 9 ? "" : "0"; 0081 String secsPad = sec > 9 ? "" : "0"; 0082 value = hoursPad + hours + minsPad + mins + secsPad + secs; 0083 } else { 0084 value = hours + mins + secs; 0085 } 0086 return value; 0087 0088 } 0089 0090 // Remove timestamp in 01h02m34s or 1h2m34s or 02m34s or 2m34s or 01s or 1s format. 0091 // Can also nandle rimestamps in 1234s format if called with 's' trailer 0092 private static URL stripTimestampHMS(URL url, String parameter, String trailer, boolean inQuery) 0093 throws MalformedURLException { 0094 String regex = parameter + "([\\d]+[hH])?([\\d]+[mM])?[\\d]+[sS]" + trailer + "&?"; 0095 return stripTimestampCommon(url, inQuery, regex); 0096 } 0097 0098 0099 // Remove timestamp in 1234 format 0100 private static URL stripTimestampS(URL url, String parameter, String trailer, boolean inQuery) 0101 throws MalformedURLException { 0102 String regex = parameter + "[\\d]+" + trailer + "&?"; 0103 return stripTimestampCommon(url, inQuery, regex); 0104 } 0105 0106 private static URL stripTimestampCommon(URL url, boolean inQuery, String regex) 0107 throws MalformedURLException { 0108 String value; 0109 if (inQuery) { 0110 value = url.getQuery(); 0111 } else { 0112 value = url.getRef(); 0113 } 0114 if (value == null) { 0115 return url; 0116 } 0117 String newValue = value.replaceAll(regex, ""); 0118 String replaced = url.toString().replaceFirst(value, newValue); 0119 if (inQuery && replaced.endsWith("&")) { 0120 replaced = replaced.substring(0, replaced.length() - 1); 0121 } 0122 return new URL(replaced); 0123 } 0124 0125 private static URL formatUrlWithSeek(URL url, String position, String parameter, String trailer, 0126 boolean inQuery) throws MalformedURLException { 0127 String value; 0128 String separator; 0129 String newValue; 0130 if (inQuery) { 0131 value = url.getQuery(); 0132 separator = "?"; 0133 } else { 0134 value = url.getRef(); 0135 separator = "#"; 0136 } 0137 if (value == null) { 0138 newValue = String.format(Locale.getDefault(), "%s%s%s%s%s", 0139 url, separator, parameter, position, trailer); 0140 return new URL(newValue); 0141 } 0142 if (inQuery) { 0143 newValue = String.format(Locale.getDefault(), "%s&%s%s%s", 0144 value, parameter, position, trailer); 0145 } else { 0146 newValue = String.format(Locale.getDefault(), "%s%s%s", 0147 parameter, position, trailer); 0148 } 0149 return new URL(url.toString().replaceFirst(value, newValue)); 0150 } 0151 }