From: eru Date: Sun, 15 Jan 2017 12:20:45 +0000 (+0900) Subject: FLV配信用パッチをマージ。(github:niwakazoider/peercast@21998fef7e24f437ef8d50e17562ba95eb5c1843) X-Git-Tag: IM0051 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;p=peercast-im%2FPeerCastIM.git FLV配信用パッチをマージ。(github:niwakazoider/peercast@21998fef7e24f437ef8d50e17562ba95eb5c1843) VS2008でビルドが通らないのでパッチを一部修正。 消えていたREADMEを復旧。 --- diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..b7bb3fd --- /dev/null +++ b/README.txt @@ -0,0 +1,180 @@ +PeerCast IM0051 (released on 20160115 by えるー) +based on PeerCast IM7651 by Trill, Original: (c) 2005-2007 giles/peercast.org + + += 概要 + IM7651に以下の機能修正を施した物。 + + - 直下を取っているチャンネルのBump時に確認メッセージを表示。 + + - 起動時に自動でGUIを開く機能(オプション) + + - GUI表示時に自動で最前面とする機能(オプション) + + - チャンネル毎にリレー数の上限を設定できる機能。 + + チャンネル情報ダイアログより変更できます。 + + 0に設定した場合には既定値が利用されます。 + + index.txtについては設定画面で個別設定が可能なので + チャンネル情報からは変更できません。 + + - トラフィックモニタ + + PeerCastの再起動でリセット。 + + - エラー落ち時のログダンプ機能 + + 強制終了した際、ぴあかすのインストールディレクトリに + dump.html、dump.dmpというファイルが生成されます。 + そのログを渡して貰えると喜びますが、事前に4種類のログ全てを + 記録する様に設定をお願いします。 + + - FLV配信に対応 + + += 諸注意 + - 1. 動作について + 不具合などによる責任は負いかねます。At your own risk。 + また動作確認はXP SP3/Win7のみで実施しており、その他の環境における動作 + については一切保証しません。 + + - 2. 同梱のDLLについて + + 1。dbghelp.dll (6.9.3.113) + このDLLはDebugging Tools for Windows(6.9.3.113)に含まれる再頒布可能 + コンポーネントであり、その権利はMicrosoftに帰属します。 + また再頒布はこのプログラムと共に行う場合のみ許可されます。 + + += 既知のバグ + - 視聴中のチャンネルを切断した場合、強制終了する場合があります。 + チャンネルの切断はリレーが停止した後に行うようにしてください。 + + += 改訂履歴 + - IM0051 (170115) + + FLVの配信に対応。 + RTMPの受け入れ機能は無いのでFlazrDumper等、HTTPで流せるツールが必要です。 + (Thanks to github:niwakazoider/peercast@21998fe) + + - IM0050 (160111) + + FLV配信の視聴・リレーに対応。(チケット#29363) + + - IM0045 (120506) + + DoS攻撃への耐性を向上。 + + - IM0044 (110309) + + GUIの右クリックメニューからリレーしていないチャンネル情報を + 一括削除できるようになりました。 + + - IM0043 (110129) + + WebGUIのレスポンスが低下していた不具合を修正。 + + 今回からx86版コアをSSE2オプション付きのみに変更。 + SSE2非対応CPUで動作しない場合はソースからコンパイルしてください。 + + - IM0042 (101120) + + チャンネル切断直後に同じチャンネルを開くと強制終了する場合が + あったのを修正。 + + - IM0041 (101023) + + Android OSからの再生に対応。 + チャンネルURL(http://host:ip/pls/ハッシュ値?tip=hoge)を + http://host:ip/stream/ハッシュ値.wmv?tip=hoge + と書き換え、Android OS上のブラウザから開くことで再生できます。 + ただし、WMV9 AP等による配信はAndroid OS側のデコーダが + 対応していないため再生できません。 + + VP版のGUIを追加。 + + x86版コアをSSE2のオプションを指定してコンパイルするように変更。 + SSE2非対応のCPUを使っている場合はx86_SSE_disabledフォルダの + バイナリを使用してください。 + + - IM0040 (090930) + + 再接続中のチャンネルをGUIから切断不能にした。 + + 出力するXMLが一部ライブラリ・ソフトウェアに受理されなかったのを修正。 + + バージョン情報の改竄に対応。 + + - IM0039 (090928) + + GUIからCOUTを切断できるようにした。 + + パッチをマージ。 + + - IM0038 (090705) + + 強制終了するバグを修正。 + + - IM0037 (090531) + + なんかよく分かんない修正。 + + - IM0036 (090528) + + バージョンアップ通知機能を追加。 + + - IM0035 (090523) + + デバッグ用のコードを抜き忘れてた。 + + - IM0034 (090523) + + index_xp.txtが原因で他のリレーが詰まる現象に対して非常に適当な対策。 + 効果不明な上,これがさらなる問題を生む可能性有り。 + + - IM0033 (090310) + + Vista環境でWindows Defenderがlocalhostのエイリアスを消去するバグに対応。 + + - IM0032 (090129) + + x64に暫定対応。 + + - IM0031 (080914) + + 例外処理機構を修正。 + + - IM0030 (080914) + + エラー落ちする可能性があったのを1カ所修正。 + + - IM0029 (080909) + + 例外処理機構が不完全だったのを修正。 + + - IM0028-3 (080907) + + GUIでリモートホストが表示されない事があるのを修正。 + + - IM0028-2 (080904) + + ソースアドレスがClass Dの通信を遮断。 + + - IM0028 (080818) + + ログダンプ機能を追加。 + + マイナービルド番号を増やすのもいい加減面倒くさくなってきたのでメジャーアップ。 + + - IM0027-5-2 (080628) + + トラフィックモニタが1^32で0に戻っていたのを修正。 + + - IM0027-5 (080628) + + トラフィックモニタを追加。 + + - IM0027-4-2 (080512) + + チャンネルを開いた際のメインウインドウ表示を抑止。 + + - IM0027-4 (080508) + + CVE-2008-2040を修正。 + + - IM0027-3 (080122) + + バグ修正用のパッチ(VPdiff20080120)をマージ。 + + - IM0027-2 (080106) + (注) PP版のGUIは搭載していないのでPP版の機能は使えません。 + + VP0027-1をマージ。 + + - IM0027 (071230) + (注) 未公開版 + + チャンネル毎にリレー数上限を設定できる機能を追加。 + + - IM0026-2 (071226) + (注) 動作そのものに修正は加わっていません。あくまで表面的な修正のみです。 + + 再接続時、GUIの表示が一時的にエラーとなるのを修正。 + + たまにGUIの表示(下流リレー)がバグるのを(多分)修正。 + + - IM0026 (071223) + + バージョン表記の変更。 + + 内部データのロックに問題があったのを修正。 + + VPdiff20071223(生命キャスト対策コード/ツールスレ24-517)をマージ。 + + マージによる変更点。 + ・下流情報の送信に簡単な帯域制限を付加。 + ・下流情報内のuphostで示されるホストが下流に存在しない場合、その下流情報は捨てる。 + ・下流情報を送信するとき、直下のホスト情報が必ず送信されるように修正。 + ・大きすぎるリスナー数、リレー数を制限。 + ・チャンネル要求時に自ホストのリスンポートを通知。 + ・紫ホストの自動切断を行うコードを修正。 + ・index.txtがオートBumpされるまでの時間を延長。 + + - IM7650 + + 初版。幾つかバージョン違いがあるけど肝心のバージョン表記は一緒なので区別できない。 + + VP26までの変更内容(GUI除く)をマージ。 diff --git a/core/common/channel.cpp b/core/common/channel.cpp index 970ac9a..7168616 100644 --- a/core/common/channel.cpp +++ b/core/common/channel.cpp @@ -39,6 +39,7 @@ #include "ogg.h" #include "mms.h" #include "nsv.h" +#include "flv.h" #include "icy.h" #include "url.h" @@ -1374,6 +1375,10 @@ ChannelStream *Channel::createSource() LOG_CHANNEL("Channel is OGG"); source = new OGGStream(); break; + case ChanInfo::T_FLV: + LOG_CHANNEL("Channel is FLV"); + source = new FLVStream(); + break; default: LOG_CHANNEL("Channel is Raw"); source = new RawStream(); @@ -2363,7 +2368,6 @@ Channel *ChanMgr::findAndRelay(ChanInfo &info) return NULL; } - if (c->isPlaying() && (c->info.contentType!=ChanInfo::T_UNKNOWN)) break; @@ -3997,6 +4001,7 @@ const char *ChanInfo::getTypeStr(TYPE t) case T_MPG: return "MPG"; case T_NSV: return "NSV"; case T_WMV: return "WMV"; + case T_FLV: return "FLV"; case T_PLS: return "PLS"; case T_ASX: return "ASX"; @@ -4052,6 +4057,8 @@ const char *ChanInfo::getTypeExt(TYPE t) return ".wmv"; case ChanInfo::T_WMA: return ".wma"; + case ChanInfo::T_FLV: + return ".flv"; default: return ""; } @@ -4100,6 +4107,8 @@ ChanInfo::TYPE ChanInfo::getTypeFromStr(const char *str) return T_WMA; else if (stricmp(str,"WMV")==0) return T_WMV; + else if (stricmp(str,"FLV")==0) + return T_FLV; else if (stricmp(str,"PLS")==0) return T_PLS; else if (stricmp(str,"M3U")==0) diff --git a/core/common/channel.h b/core/common/channel.h index 17c4a2c..97ab1da 100644 --- a/core/common/channel.h +++ b/core/common/channel.h @@ -95,6 +95,8 @@ public: T_WMA, T_WMV, + T_FLV, + T_PLS, T_ASX }; diff --git a/core/common/flv.cpp b/core/common/flv.cpp new file mode 100644 index 0000000..562ef13 --- /dev/null +++ b/core/common/flv.cpp @@ -0,0 +1,136 @@ +// ------------------------------------------------ +// File : flv.cpp +// Date: 14-jan-2017 +// Author: niwakazoider +// +// Modified by Eru @2017.1.15 for compilation error at VS2008 +// +// (c) 2002-3 peercast.org +// ------------------------------------------------ +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// ------------------------------------------------ + +#include "channel.h" +#include "flv.h" +#include "string.h" +#include "stdio.h" +#ifdef _DEBUG +#include "chkMemoryLeak.h" +#define DEBUG_NEW new(__FILE__, __LINE__) +#define new DEBUG_NEW +#endif + + +// ------------------------------------------ +void FLVStream::readEnd(Stream &, Channel *) +{ +} + +// ------------------------------------------ +void FLVStream::readHeader(Stream &, Channel *) +{ +} + +// ------------------------------------------ +int FLVStream::readPacket(Stream &in, Channel *ch) +{ + bool headerUpdate = false; + + if (ch->streamPos == 0) { + bitrate = 0; + FLVFileHeader header = FLVFileHeader(); + header.read(in); + fileHeader = header; + headerUpdate = true; + } + + FLVTag flvTag; + flvTag.read(in); + + switch (flvTag.type) + { + case TAG_SCRIPTDATA: + { + AMFObject amf; + MemoryStream flvmem = MemoryStream(flvTag.data, flvTag.size); + if (amf.readMetaData(flvmem)) { + flvmem.close(); + bitrate = amf.bitrate; + metaData = flvTag; + headerUpdate = true; + } + } + case TAG_VIDEO: + { + //AVC Header + if (flvTag.data[0] == 0x17 && flvTag.data[1] == 0x00 && + flvTag.data[2] == 0x00 && flvTag.data[3] == 0x00) { + avcHeader = flvTag; + headerUpdate = true; + } + } + case TAG_AUDIO: + { + //AAC Header + if (flvTag.data[0] == 0xaf && flvTag.data[1] == 0x00) { + aacHeader = flvTag; + headerUpdate = true; + } + } + } + + if (headerUpdate && fileHeader.size>0) { + int len = fileHeader.size; + if (metaData.type==TAG_SCRIPTDATA) len += metaData.packetSize; + if (avcHeader.type == TAG_VIDEO) len += avcHeader.packetSize; + if (aacHeader.type == TAG_AUDIO) len += aacHeader.packetSize; + MemoryStream mem = MemoryStream(ch->headPack.data, len); + mem.write(fileHeader.data, fileHeader.size); + if (metaData.type == TAG_SCRIPTDATA) mem.write(metaData.packet, metaData.packetSize); + if (avcHeader.type == TAG_VIDEO) mem.write(avcHeader.packet, avcHeader.packetSize); + if (aacHeader.type == TAG_AUDIO) mem.write(aacHeader.packet, aacHeader.packetSize); + + ch->info.bitrate = bitrate; + + ch->headPack.type = ChanPacket::T_HEAD; + ch->headPack.len = mem.pos; + ch->headPack.pos = ch->streamPos; + ch->newPacket(ch->headPack); + + ch->streamPos += ch->headPack.len; + } + else { + ChanPacket pack; + + MemoryStream mem = MemoryStream(flvTag.packet, flvTag.packetSize); + + int rlen = flvTag.packetSize; + while (rlen) + { + int rl = rlen; + if (rl > ChanMgr::MAX_METAINT) + rl = ChanMgr::MAX_METAINT; + + pack.init(ChanPacket::T_DATA, pack.data, rl, ch->streamPos); + mem.read(pack.data, pack.len); + ch->newPacket(pack); + ch->checkReadDelay(pack.len); + ch->streamPos += pack.len; + + rlen -= rl; + } + + mem.close(); + + } + + return 0; +} diff --git a/core/common/flv.h b/core/common/flv.h new file mode 100644 index 0000000..53410a5 --- /dev/null +++ b/core/common/flv.h @@ -0,0 +1,277 @@ +// ------------------------------------------------ +// File : flv.h +// Date: 14-jan-2017 +// Author: niwakazoider +// +// Modified by Eru @2017.1.15 for compilation error at VS2008 +// +// (c) 2002-3 peercast.org +// ------------------------------------------------ +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// ------------------------------------------------ + +#ifndef _FLV_H +#define _FLV_H + +#include "channel.h" +#include "stdio.h" + + +const int TAG_SCRIPTDATA = 18; +const int TAG_AUDIO = 8; +const int TAG_VIDEO = 9; + +// ----------------------------------- +class FLVFileHeader +{ +public: + FLVFileHeader() : size(0), data(NULL) + { + } + + void read(Stream &in) + { + size = 13; + data = (char *)malloc(size); + in.read(data, size); + + if (data[0] == 0x46 && //F + data[1] == 0x4c && //L + data[2] == 0x56) { //V + version = data[3]; + } + } + int version; + int size; + char *data; +}; + + +// ----------------------------------- +class FLVTag +{ +public: + enum TYPE + { + T_UNKNOWN, + T_SCRIPT, + T_AUDIO, + T_VIDEO + }; + + FLVTag() + { + size = 0; + type = T_UNKNOWN; + data = NULL; + packet = NULL; + } + + void read(Stream &in) + { + if (data != NULL) free(data); + if (packet != NULL) free(packet); + + unsigned char binary[11]; + in.read(binary, 11); + + type = binary[0]; + size = (binary[1] << 16) | (binary[2] << 8) | (binary[3]); + //int timestamp = (binary[7] << 24) | (binary[4] << 16) | (binary[5] << 8) | (binary[6]); + //int streamID = (binary[8] << 16) | (binary[9] << 8) | (binary[10]); + data = (char *)malloc(size); + in.read(data, size); + + unsigned char prevsize[4]; + in.read(prevsize, 4); + + packet = (char *)malloc(11+size+4); + memcpy(packet, binary, 11); + memcpy(packet+11, data, size); + memcpy(packet+11+size, prevsize, 4); + packetSize = 11 + size + 4; + } + + const char *getTagType() + { + switch (type) + { + case TAG_SCRIPTDATA: + return "Script"; + case TAG_VIDEO: + return "Video"; + case TAG_AUDIO: + return "Audio"; + } + return "Unknown"; + } + + int size; + int packetSize; + char type; + char *data; + char *packet; +}; + + + +// ---------------------------------------------- +class FLVStream : public ChannelStream +{ +public: + int bitrate; + FLVFileHeader fileHeader; + FLVTag metaData; + FLVTag aacHeader; + FLVTag avcHeader; + FLVStream() + { + fileHeader = FLVFileHeader(); + metaData = FLVTag(); + aacHeader = FLVTag(); + avcHeader = FLVTag(); + bitrate = 0; + } + virtual void readHeader(Stream &, Channel *); + virtual int readPacket(Stream &, Channel *); + virtual void readEnd(Stream &, Channel *); +}; + +class AMFObject +{ +public: + AMFObject() : bitrate(0) + { + // nothing to do + } + + static const int AMF_NUMBER = 0x00; + static const int AMF_BOOL = 0x01; + static const int AMF_STRING = 0x02; + static const int AMF_OBJECT = 0x03; + static const int AMF_MOVIECLIP = 0x04; + static const int AMF_NULL = 0x05; + static const int AMF_UNDEFINED = 0x06; + static const int AMF_REFERENCE = 0x07; + static const int AMF_ARRAY = 0x08; + static const int AMF_OBJECT_END = 0x09; + static const int AMF_STRICTARRAY = 0x0a; + static const int AMF_DATE = 0x0b; + static const int AMF_LONG_STRING = 0x0c; + + bool readBool(Stream &in) + { + return in.readChar() != 0; + } + + int readInt(Stream &in) + { + return (in.readChar() << 24) | (in.readChar() << 16) | (in.readChar() << 8) | (in.readChar()); + } + + char* readString(Stream &in) + { + int len = (in.readChar() << 8) | (in.readChar()); + if (len == 0) { + return NULL; + } + else { + char* data = (char *)malloc(len+1); + *(data+len) = '\0'; + in.read(data, len); + return data; + } + }; + + double readDouble(Stream &in) + { + char* data = (char *)malloc(sizeof(double)); + for (int i = 8; i > 0; i--) { + char c = in.readChar(); + *(data + i - 1) = c; + } + double number = *reinterpret_cast(data); + return number; + }; + + void readObject(Stream &in) + { + while (true) { + char* key = readString(in); + if (key == NULL) { + break; + } + else { + if (strcmp(key, "audiodatarate") == 0) { + in.readChar(); + bitrate += static_cast(readDouble(in)); + } + else if (strcmp(key, "videodatarate") == 0) { + in.readChar(); + bitrate += static_cast(readDouble(in)); + } + else { + read(in); + } + } + } + in.readChar(); + } + + bool readMetaData(Stream &in) + { + char type = in.readChar(); + if (type == AMF_STRING) { + char* name = readString(in); + if (strcmp(name, "onMetaData") == 0) { + bitrate = 0; + read(in); + } + } + return bitrate > 0; + } + + void read(Stream &in) + { + char type = in.readChar(); + if (type == AMF_NUMBER) { + readDouble(in); + } + else if (type == AMF_BOOL) { + readBool(in); + } + else if (type == AMF_STRING) { + readString(in); + } + else if (type == AMF_OBJECT) { + readObject(in); + } + else if (type == AMF_OBJECT_END) { + } + else if (type == AMF_ARRAY) { + int len = readInt(in); + readObject(in); + } + else if (type == AMF_STRICTARRAY) { + int len = readInt(in); + for (int i = 0; i < len; i++) { + read(in); + } + } + else if (type == AMF_DATE) { + in.skip(10); + } + } + int bitrate; +}; + + +#endif diff --git a/core/common/http.h b/core/common/http.h index 8f60404..6970170 100644 --- a/core/common/http.h +++ b/core/common/http.h @@ -74,6 +74,8 @@ static const char *MIME_RAM = "audio/x-pn-realaudio"; static const char *MIME_WMA = "audio/x-ms-wma"; static const char *MIME_WMV = "video/x-ms-wmv"; +static const char *MIME_FLV = "video/flv"; + static const char *MIME_HTML = "text/html"; static const char *MIME_XML = "text/xml"; static const char *MIME_CSS = "text/css"; diff --git a/core/common/version2.h b/core/common/version2.h index f47498e..d22c26f 100644 --- a/core/common/version2.h +++ b/core/common/version2.h @@ -44,9 +44,9 @@ extern int version_ex; // VERSION_EX #if 1 /* for VP extend version */ //#define VERSION_EX 1 static const char *PCP_CLIENT_VERSION_EX_PREFIX = "IM"; // 2bytes only -static const int PCP_CLIENT_VERSION_EX_NUMBER = 50; -static const char *PCX_AGENTEX = "PeerCast/0.1218(IM0050)"; -static const char *PCX_VERSTRING_EX = "v0.1218(IM0050)"; +static const int PCP_CLIENT_VERSION_EX_NUMBER = 51; +static const char *PCX_AGENTEX = "PeerCast/0.1218(IM0051)"; +static const char *PCX_VERSTRING_EX = "v0.1218(IM0051)"; static const char *PCP_CLIENT_DIST_URL = "http://pecaim.net/"; static const char *PCP_CLIENT_VERSION_URL = "version.pecaim.net"; diff --git a/core/win32/lib/corelib.vcproj b/core/win32/lib/corelib.vcproj index 887649a..81dde17 100644 --- a/core/win32/lib/corelib.vcproj +++ b/core/win32/lib/corelib.vcproj @@ -1249,6 +1249,31 @@ + + + + + + + + + + + + + + + diff --git a/ui/win32/simple/Simple.vcproj b/ui/win32/simple/Simple.vcproj index ad72611..933faeb 100644 --- a/ui/win32/simple/Simple.vcproj +++ b/ui/win32/simple/Simple.vcproj @@ -1045,7 +1045,6 @@ />