如何使用ffmpeg将mp4转换为m3u8
如何使用ffmpeg将mp4转换为m3u

如何使用ffmpeg将mp4转换为m3u8

M3U8 是一种基于文本的播放列表格式,通常用于 HTTP Live Streaming(HLS)协议,该协议是由苹果公司开发的一种流媒体传输方式。M3U8 文件包含了指向媒体片段(如视频或音频)的 URL 链接,这些片段会被播放器逐个请求并拼接起来,以达到流畅播放的效果。

阅读全文
TS试炼-9
TS试炼-9

TS试炼-9

包含:Parse URL Params(解析URL参数)、获取数组的中间元素、找出目标数组中只出现过一次的元素、统计数组中的元素个数、整数、将类型为字面类型(标签类型)的属性,转换为基本类型、DeepMutable(深度可变)、All(元组每项与传入类型相同)、Filter(过滤)、FindAll(获取所有下标)

阅读全文
TS试炼-10
TS试炼-10

TS试炼-10

包含:Combination key type(组合键类型)、Permutations of Tuple(元组全排列)

阅读全文

⌈工具⌋ 在队列中执行异步函数

根据传入的函数,及参数数组,按队列执行,并可配置最大同时执行个数。

javascript 复制代码
/**
 * 队列执行函数
 * @param {Function} asyncFunction 异步函数
 * @param {Array} items 数据数组
 * @param {Number} maxConcurrent 最大并行
 * @returns
 */
export function executeAsyncFunctionInQueue(
  asyncFunction,
  items,
  maxConcurrent = 10
) {
  items = items.slice()
  return new Promise((resolve) => {
    const total = items.length
    const results = []
    const executing = new Set()
    const executeNext = async () => {
      if (items.length === 0) {
        return
      }
      const currentIndex = total - items.length
      const item = items.shift()
      const promise = asyncFunction(item, currentIndex)
        .then((result) => {
          results.push(result)
        })
        .catch((error) => {
          results.push(error)
        })
        .finally(() => {
          executing.delete(promise)
          if (executing.size || items.length) {
            executeNext()
          } else {
            resolve(results)
          }
        })
      executing.add(promise)
    }
    while (executing.size < maxConcurrent && items.length > 0) {
      executeNext()
    }
  })
}
2024-12-23

⌈地理⌋ 获取两点间的距离

获取两点间的距离。

javascript 复制代码
/**
 * 获取两点间的距离
 * @param { { lat: number, lng: number } } point1 - 第一个点的经纬度
 * @param { { lat: number, lng: number } } point2 - 第二个点的经纬度
 * @param { boolean } kilometreFlag - 单位标志:true返回公里(km)并保留1位小数,false返回米(m)并取整
 * @returns { number } 两点间的距离
 */
export function getDistance(point1, point2, kilometreFlag = false) {
  const { lng: lng1, lat: lat1 } = point1
  const { lng: lng2, lat: lat2 } = point2
  // 将角度转换为弧度
  const rad = (d) => (d * Math.PI) / 180
  // 将经纬度从角度转换为弧度
  const radLat1 = rad(lat1)
  const radLat2 = rad(lat2)
  // 计算纬度和经度的差值(弧度)
  const a = radLat1 - radLat2
  const b = rad(lng1) - rad(lng2)
  // 使用哈弗辛公式计算两点间的球面距离
  let s =
    2 *
    Math.asin(
      Math.sqrt(
        Math.pow(Math.sin(a / 2), 2) +
          Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)
      )
    )
  // 乘以地球半径(6378.137公里)得到距离(公里)
  s = s * 6378.137
  // 根据单位标识返回不同单位和精度的结果
  if (kilometreFlag) {
    // 返回公里单位,保留1位小数
    s = Number(s.toFixed(1))
  } else {
    // 返回米单位,四舍五入取整
    s = Number(Math.round(s * 1000).toFixed(0))
  }
  return s
}
2025-11-24

⌈地理⌋ 获取坐标的是否在围栏内

判断指定经纬度位置,是否在电子围栏内部。

javascript 复制代码
/**
 * 获取坐标的是否在围栏内
 * @param { { lat: number, lng: number } } point 坐标
 * @param { { lat: number, lng: number }[] } APoints 围栏
 * @returns { boolean } 在围栏内返回true,否则false
 */
export function isPointInPolygon(point, APoints) {
  const { lat, lng } = point
  let iSum = 0
  let dLon1, dLon2, dLat1, dLat2, dLon
  if (APoints.length < 3) return false
  const iCount = APoints.length
  for (let i = 0; i < iCount; i++) {
    if (i == iCount - 1) {
      dLon1 = APoints[i].lng
      dLat1 = APoints[i].lat
      dLon2 = APoints[0].lng
      dLat2 = APoints[0].lat
    } else {
      dLon1 = APoints[i].lng
      dLat1 = APoints[i].lat
      dLon2 = APoints[i + 1].lng
      dLat2 = APoints[i + 1].lat
    }
    //以下语句判断A点是否在边的两端点的水平平行线之间,在则可能有交点,开始判断交点是否在左射线上
    if ((lat >= dLat1 && lat < dLat2) || (lat >= dLat2 && lat < dLat1)) {
      if (Math.abs(dLat1 - dLat2) > 0) {
        //得到 A点向左射线与边的交点的x坐标:
        dLon = dLon1 - ((dLon1 - dLon2) * (dLat1 - lat)) / (dLat1 - dLat2)
        if (dLon < lng) iSum++
      }
    }
  }
  if (iSum % 2 != 0) return true
  return false
}
2025-11-24

⌈工具⌋ 在队列中执行异步函数

使用async\await实现队列执行

javascript 复制代码
/**
 * 队列执行函数
 * @param asyncFunction 异步函数
 * @param items  参数数组
 * @param maxConcurrent  最大并发数
 * @returns 结果数组
 */
async executeAsyncFunctionInQueue<T, K>(
  asyncFunction: (item: K, index: number) => Promise<T>,
  items: K[],
  maxConcurrent: number = 10
): Promise<Array<T | Error>> {
  const queue = [...items]
  const results: Array<T | Error> = new Array(items.length)
  const executing = new Set<Promise<void>>()

  const executeNext = async (): Promise<void> => {
    if (queue.length === 0) return

    const currentIndex = items.length - queue.length
    const item = queue.shift()!

    const promise = (async () => {
      try {
        const result = await asyncFunction(item, currentIndex)
        results[currentIndex] = result
      } catch (error) {
        results[currentIndex] =
          error instanceof Error ? error : new Error(String(error))
      }
    })()

    executing.add(promise)
    await promise
    executing.delete(promise)

    if (queue.length > 0) {
      await executeNext()
    }
  }

  const workers = Array.from(
    { length: Math.min(maxConcurrent, queue.length) },
    () => executeNext()
  )

  await Promise.all(workers)
  return results
}
2025-01-03
风骚律师第六季

风骚律师第六季

故事发展到第六季,吉米(鲍勃·奥登科克 Bob Odenkirk 饰)和金(蕾亚·希霍恩 Rhea Seehorn 饰)决定对霍华德(帕特里克·法比安 Patrick Fabian 饰)实行小小的“复仇”。那边厢,纳乔(迈克尔·曼多 Michael Mando 饰)在将萨拉曼卡家族一锅端之后踏上了逃往的旅途。  这场屠杀中,拉罗(托尼·达尔顿 Tony Dalton 饰)成为了幸存者,这对于纳乔和古斯(吉安卡罗·埃斯波西托 Giancarlo Esposito 饰)来说无疑是一场不幸。古斯一边派出麦克(乔纳森·班克斯 Jonathan Banks 饰)接应纳乔,一边还要提防血债血偿的拉罗随时出现在眼前。最终,吉米和金顺利的毁掉了霍华德的事业,但事情的发现很显然超越了两人的预期和控制。

2024-06-22
进击的巨人

进击的巨人

在艾伦他们居住的帕拉迪岛之外,还存在一个其他人类居住的世界。当中一个国家「玛雷」与其他各国爆发战争。陷入苦战之际,他们决定要攻进帕拉迪岛,把「始祖的巨人」抢过来。在这里又看到另一群孩子们拼命求生存的身影……

2024-07-19
绝命毒师第五季

绝命毒师第五季

故事紧接着上一季,通过一场精心策划的大爆炸,沃尔特(布莱恩·科兰斯顿 Bryan Cranston 饰)终于除掉了长久以来的威胁古斯塔沃(吉安卡洛·埃斯珀西多 Giancarlo Esposito 饰),也将古斯塔沃一手建立的毒品帝国连根拔起。然而,“事业”上的成功并没有为沃尔特带来太多的快乐,因为他和妻子斯凯勒(安娜·古恩 Anna Gunn 饰)之间的关系再次跌落到了冰点。  古斯塔沃死了,但沃尔特的野心并没有消失,他联手杰西(亚伦·保尔 Aaron Paul 饰)与麦克(乔纳森·班克斯 Jonathan Banks 饰),开始建立属于他的新的帝国。一次偶然中,汉克(迪恩·诺里斯 Dean Norris 饰)在沃尔特家中发现了沃尔特就是海森堡的确凿证据,巨大的打击之下,他决心大义灭亲,昔日的连襟,如今沦为对手。与此同时,一股新的势力正在毒品圈内逐渐壮大,他们即将成为汉克最强大的敌人。

2024-07-19
绝命毒师第四季

绝命毒师第四季

故事发展到第四季,沃尔特(布莱恩·科兰斯顿 Bryan Cranston 饰)和古斯(吉安卡洛·埃斯珀西多 Giancarlo Esposito 饰)之间的关系开始变得越来越紧张起来,古斯不仅加强了对于沃尔特的监视,还企图控制杰西(亚伦·保尔 Aaron Paul 饰),希望有朝一日他能够替代沃尔特。  一些蛛丝马迹让汉克(迪恩·诺里斯 Dean Norris 饰)对古斯逐渐产生了怀疑,这让沃尔特的身份几次濒临暴露。沃尔特发现了古斯对自己的杀意,他想要用积攒下来的存款带着家人远走高飞,哪想到,巨额财产竟被斯凯勒(安娜·古恩 Anna Gunn 饰)用于自保。沃尔特被逼到了绝境,在他的面前只有唯一的选择,那就是不惜一切代价,先下手为强,除掉古斯。

2024-07-19