安卓磁链搜索下载播放和原理探索

版权声明:本文由于码字辛苦,转载请注明出处。 https://blog.csdn.net/baidu_25797177/article/details/84324074

安卓磁链搜索下载播放

了解磁链原理和使用,资源搜索必备神器

效果图

在这里插入图片描述

磁力搜索

获取磁链

抓取网络资源接口返回磁链地址

source 可选 种子搜|磁力吧|BT兔子|idope|BTDB|BT4G|屌丝搜|AOYOSO

http://bt.xiandan.in/api/search?&source=种子搜&keyword=测试&page=1

返回JSON

{
  "currentPage": 1,
  "currentSourceSite": "种子搜",
  "results": [
    {
      "magnet": "magnet:?xt=urn:btih:b9f4c386974037282b077e516eced7ae50e57b7f",
      "name": "[星火字幕组][填坑][beta测试版非正式版][名侦探柯南剧场版M19][业火的向日葵][1080P][10bit][简日附带假名].mkv ",
      "formatSize": "6.83 GB",
      "size": 7333656576,
      "count": "2018-06-03",
      "detailUrl": "http://www.zhongzijun.com/info-b9f4c386974037282b077e516eced7ae50e57b7f",
      "resolution": "1080P"
    },
    {
      "magnet": "magnet:?xt=urn:btih:71ed94a7e48585fddeb178b5cb88afaf8354c1b4",
      "name": "2018_05_16园博园迈腾测试 ",
      "formatSize": "62.31 MB",
      "size": 65336772,
      "count": "2018-05-28",
      "detailUrl": "http://www.zhongzijun.com/info-71ed94a7e48585fddeb178b5cb88afaf8354c1b4",
      "resolution": ""
    }
  ]
}

磁链下载

首先非常感谢开源项目和资料

[1] https://github.com/masterwok/simple-torrent-android

[2] https://github.com/frostwire/frostwire-jlibtorrent

[3] https://github.com/dueeeke/dkplayer

[4] http://www.bittorrent.org/

[5] https://www.bbsmax.com/A/q4zVmvGGdK/

[6] http://www.bubuko.com/infodetail-1744428.html

开始查找下载数据

val torrentSessionOptions = TorrentSessionOptions(downloadLocation = File(rootPath), onlyDownloadLargestFile = true, enableLogging = false, shouldStream = true)
torrentSession = TorrentSession(torrentSessionOptions)
torrentSession?.listener = object : TorrentSessionListener {
    ...
    //各个状态监听
    ...
}

下载完成播放器

下载到本地文件夹,直接读取播放即可

//xml
<com.dueeeke.videoplayer.player.IjkVideoView
        android:id="@+id/video_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />  

//kt
val controller = FullScreenController(this)
        val playerConfig = PlayerConfig.Builder()
                .usingSurfaceView() //启用SurfaceView显示视频,不调用默认使用TextureView
                .savingProgress() //保存播放进度
                .disableAudioFocus() //关闭AudioFocusChange监听
                .build()
        video_view.setPlayerConfig(playerConfig)
        video_view.setUrl(intent.getStringExtra("url"))
        video_view.title = intent.getStringExtra("title")
        video_view.setVideoController(controller)
        video_view.startFullScreen()
        video_view.start()

调用迅雷打开磁链

由于从tracker上获取不到的情况比较多, 所以还是直接调用迅雷打开比较快

private fun wakeThunder(link: String) {
    //AAlinkZZ 不用转thunder://xxx 可以直接让迅雷识别magnet
    var intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
    intent.addCategory("android.intent.category.DEFAULT")
    startActivity(intent)
        
}

原理分析

网上找了好久, 摘取自各个文章拼接再加上自己的理解…

磁力链接

磁力链接 的主要作用是识别能够通过“点对点技术(即:P2P)”下载的文件

这种链接是通过不同文件内容的Hash结果生成一个纯文本的“数字指纹”,来识别文件的。而不是基于文件的位置或者名称。 这就类似生活中消费品包装上常见的条码。

//例如
magnet:?xt=urn:btih:E8488E0F3F5B891234DED8555877AC712A0E4

我们来分析一下这个链接:

magnet:此链接采用的协议名称;

xt:Exact Topic的缩写,包含文件Hash值的统一资源名称;

btih:BitTorrent Info Hash的缩写,这里表示采用了Hash方法名。此外,btih还可以替换为ed2k、aich、sha1或md5等等。它表示的是这个文件唯一的标识符。

这三项是一条Magnet URL中,必不可少的组成部分。在一些Magnet URL中还会出现dn、tr、ws等等缩写,它们均为选填字段,这里就不多做介绍。

简单来说,不管你想下载任何文件,只要找到了它的Magnet URL,不需要其他任何多余的信息,你立即就能开始BT下载这个文件。

磁力链接 是通过DHT网络来索引需要下载的文件的,因此在某些环境下可能出现“获取磁力链接信息”时间较长,或者获取失败的问题。拿到磁链后需要自行组装成种子文件才能到 tracker 服务器去寻找持有下载过的Peer去获取数据。

torrent种子文件

torrent种子文件本质上是文本文件,包含Tracker信息文件信息两部分。Tracker信息主要是BT下载中需要用到的Tracker服务器的地址和针对Tracker服务器的设置,文件信息是根据对目标文件的计算生成的,计算结果根据BitTorrent协议内的Bencode规则进行编码。它的主要原理是需要把提供下载的文件虚拟分成大小相等的块,块大小必须为2k的整数次方(由于是虚拟分块,硬盘上并不产生各个块文件),并把每个块的索引信息和Hash验证码写入种子文件中;所以,种子文件就是被下载文件的“索引”。

构成成份如下:

announce:Tracker的主服务器,例如http://tracker.cnxp.com:8080/announce。

announce-list:可选,备用tracker服务器列表,例如http://tracker.cnxp.com:8080/announce,http://btfans.3322.org:6969/announce等。

creationdate:可选,torrent文件的创建日期,使用标准的UNIX时间,例1152105243。

comment:可选,种子文件的注释

createdby:可选,制作.torrent文件的工具

encoding:可选,发布的资源使用的编码方式, 比如GB2312,Big5,utf-8等

info:发布的文件的信息。所有关于下载的文件的信息都在这个字段里,它包括多个子字段,而且根据下载的是单个文件还是多个文件,子字段的项目会不同

说到info就不得不说INFO_HASH,这个值是info字段的HASH值,20个Byte,同样是使用SHA1作为HASH函数。由于info字段是发布的文件信息构成的,所以INFO_HASH在BT协议中是用来识别不同的种子文件的。基本上每个种子文件的INFO_HASH都是不同的(至少现在还没有人发现有SHA的冲突),所以BT服务器以及客户端都是以这个值来识别不同的种子文件的。

文件结构

多文件Torrent的结构的树形图为:

Multi-file Torrent
|─announce
|─announce-list
|─comment
|─comment.utf-8
|─creation date
|─encoding
|─info
│ |─files
│ │ |─length
│ │ |─path
│ └─path.utf-8
│ |─name
│ |─name.utf-8
│ |─piece length
│ |─pieces
│ |─publisher
│ |─publisher-url
│ |─publisher-url.utf-8
│ └─publisher.utf-8
└─nodes

单文件Torrent的结构的树形图为:

Single-File Torrent
|─announce
|─announce-list
|─comment
|─comment.utf-8
|─creation date
|─encoding
|─info
│ |─length
│ |─name
│ |─name.utf-8
│ |─piece length
│ |─pieces
│ |─publisher
│ |─publisher-url
│ |─publisher-url.utf-8
│ └─publisher.utf-8
└─nodes

Tracker

BT下载是采用P2P的下载方式,下载的大致形式采用如下图所示,处于图示中心的称为TrackerServer服务器,其余称为Peer

  • 有HTTP和UDP协议两种

以HTTP Get为例请求完成Peers获取和自身的注册。请求的URL格式如下:

//例如
http://tracker.trackerfix.com:80/announce?
info_hash=94b9354069a1347e0401de80411d6a3269cd12a5&
peer_id=-TO0042-7d946ca87b91&
ip=172.16.49.194&
port=49155&
uploaded=0&
downloaded=0&
left=3192035246&
event=started&

info_hash: torrent文件中info属性的value部分(bencode格式)的SHA1 哈希值,这个哈希值是BT下载任务的唯一标识。

peer_id:任务启动时BT Client为自己随机分配的20字节的ID

ip:BTClient的外网IP

port:BTClient监听的端口

uploaded:BTClient对该任务已上传的字节数

downloaded:BTClient对该任务已下载的字节数

left:BTClient对该任务尚未下载的字节数

event:可选字段,表示BTClient对当前下载任务的状态,可选值:started,completed,stoped

这样就在把自己拥有的数据和未下载的都告诉TrackerServer中央服务器上, 其他用户下载的时候可能会通过tracker找到你的客户端来获取下载。于是就涉及到DHT协议。

DHT(分布式哈希表)

DHT由节点组成,它存储了peer的位置。BitTorrent客户端包含一个DHT节点,这个节点用来联系DHT中其他节点,从而得到peer的位置,进而通过BitTorrent协议下载。

peer:是在一个TCP端口上监听的客户端/服务器,它实现了BitTorrent协议。

节点:是在一个UDP端口上监听的客户端/服务器,它实现了DHT协议

当节点要为torrent寻找peer时,它将自己路由表中的节点ID和torrent的infohash进行距离对比。然后向路由表中离infohash最近的节点发送请求,问它们正在下载这个torrent的peer的联系信息。如果一个被联系的节点知道下载这个torrent的peer信息,那个peer的联系信息将被回复给当前节点。否则,那个被联系的节点则必须回复在它的路由表中离该torrent的infohash最近的节点的联系信息。最初的节点重复地请求比目标infohash更近的节点,直到不能再找到更近的节点为止。查询完了之后,客户端把自己作为一个peer插入到所有回复节点中离种子最近的那个节点中。

下载

在BT网络中,通过上述原理收到信息并不是种子,而是发送消息者的ipport、种子infohash(可以理解为种子的id)。我们如果想要得到种子的话,还需要做一番工作。这里涉及到另外一个非常重要的协议BEP-09,它规定了如何通过种子infohash得到种子。

大致过程。首先同我们收到的消息里边的ip:port建立TCP连接,然后发送握手消息,并告知对方自己支持BEP-09协议,然后向对方请求种子的信息,收到对方返回的种子信息后,依次或同时请求每一个块。最后所有块收集完后,对其进行拼接并通过sha1算法计算其infohash如果和我们请求的infohash值相同则保存起来,否则丢掉。

嗅探器原理

BT种子嗅探器就是利用了DHT协议得到peer信息后会向他之前查询过的节点发送通知这一点,这就是嗅探器的核心。

剩下的工作就是我们要让更多的节点发给我们通知。那么如何让更多的节点发给我们通知呢?

我们要不断的查询自己的好友节点表,并对返回回来的节点进行查询,这样才会有更多的人认识我们,别人向我们查询Target的时候,我们要伪装成Target的好友,返回结果里边包括自己,这样会有更多被查询、收到通知的机会。

//tracker地址 
https://github.com/ngosang/trackerslist

猜你喜欢

转载自blog.csdn.net/baidu_25797177/article/details/84324074