1. 程式人生 > >安卓磁鏈搜尋下載播放和原理探索

安卓磁鏈搜尋下載播放和原理探索

安卓磁鏈搜尋下載播放

瞭解磁鏈原理和使用,資源搜尋必備神器

效果圖

在這裡插入圖片描述

磁力搜尋

獲取磁鏈

抓取網路資源介面返回磁鏈地址

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