9 #include "rapidxml/rapidxml.hpp"
10 #include "rapidxml/rapidxml_utils.hpp"
11 #include "AssClass.hpp"
12 #include "danmaku2ass.h"
13 #include "danmaku2ass.hpp"
16 using namespace rapidxml
;
21 headline: the first line of comment file
29 int GetCommentType(string headline
){
30 if(headline
.find("\"commentList\":[") != std::string::npos
){
32 }else if(headline
.find("xml version=\"1.0\" encoding=\"UTF-8\"?><i") != std::string::npos
or
33 headline
.find("xml version=\"1.0\" encoding=\"utf-8\"?><i") != std::string::npos
or
34 headline
.find("xml version=\"1.0\" encoding=\"Utf-8\"?>\n") != std::string::npos
){
36 }else if(headline
.find("xml version=\"1.0\" encoding=\"UTF-8\"?><p") != std::string::npos
or
37 headline
.find("!-- BoonSutazioData=") != std::string::npos
){
46 bool CommentParser::Convert(int type
){
48 std::ifstream
input(in
);
50 getline(input
,headline
);
51 type
= GetCommentType(headline
);
55 return _convertBilibili();
61 bool CommentParser::_convertBilibili(){
65 ass
->SetDuration(duration_marquee
,duration_still
);
66 ass
->WriteHead(width
, height
, font
, fontsize
,alpha
);
68 rapidxml::file
<> xmlFile(in
);
69 if(xmlFile
.size() < 1){
72 rapidxml::xml_document
<> doc
;
75 doc
.parse
<0>(xmlFile
.data());
76 node
= doc
.first_node("i"); // Get comment main node
77 }catch(const rapidxml::parse_error
& e
){
78 std::cerr
<< "Parse error: " << e
.what() << std::endl
;
84 if(!node
->first_node("d")){
87 for (xml_node
<> *child
= node
->first_node("d"); child
; child
= child
->next_sibling()) // Each comment
92 std::string v
= child
->value();
93 bool isBlocked
= false;
94 for (auto i
= blockWords
.begin();i
!= blockWords
.end(); i
++ ){
95 if(v
.find(*i
) != std::string::npos
){
103 const char *separator
= ","; // Separator of comment properties
106 /* Arg1 : Appear time
107 The time of comment appear.
109 p
= strtok(child
->first_attribute("p")->value(), separator
);
111 float appear_time
= atof(p
);
113 /* Arg2 : Comment mode
118 7 - Positioned comment
119 8 - Javascript comment ( not convert )
121 p
= strtok(NULL
, separator
);
123 int comment_mode
= atoi(p
);
125 /* Arg3 : Font size ( not needed )*/
126 p
= strtok(NULL
, separator
);
128 //int font_size = atoi(p);
130 /* Arg4 : Font color */
131 p
= strtok(NULL
, separator
);
133 int font_color
= atoi(p
);
135 /* Arg5 : Unix timestamp ( not needed ) */
136 /* Arg6 : comment pool ( not needed ) */
137 /* Arg7 : sender uid ( not needed ) */
138 /* Arg8 : database rowID ( not needed ) */
140 ass
->AppendComment(appear_time
, comment_mode
, font_color
, child
->value());
144 ass
->WriteToDisk(disallowModes
);
150 Convert comments to .ass subtitle
152 infile: comment file path
153 outfile: output file path
158 duration_marquee:Duration of scrolling comment
159 duration_still:Duration of still comment
162 void danmaku2ass(const char *infile
,const char *outfile
,int width
,int height
,const char *font
,float fontsize
,float alpha
,float duration_marquee
,float duration_still
){
163 std::ifstream
input(infile
);
165 getline(input
,headline
);
166 int type
= GetCommentType(headline
);
167 CommentParser
*p
= new CommentParser
;
168 p
->SetFile(infile
, outfile
);
169 p
->SetRes(width
, height
);
170 p
->SetFont(font
, fontsize
);
171 p
->SetDuration(duration_marquee
, duration_still
);
174 //cout << "Avfun format detected ! Converting..." << endl;
175 cout
<< "Sorry , The format is not supported" << endl
;
177 cout
<< "Bilibili format detected ! Converting..." << endl
;
178 bool result
= p
->Convert(type
);
180 cout
<< "Convert succeed" << endl
;
182 cout
<< "Convert failed" << endl
;
185 //cout << "Niconico format detected ! Converting..." << endl;
186 cout
<< "Sorry , The format is not supported" << endl
;
188 cout
<< "ERROR: Unable to get comment type" << endl
;
195 #ifndef __danmaku2ass_native__NoMainFunc__
197 int main(int argc
,char *argv
[]){
198 cout
<< "Starting danmaku2ass native..." << endl
;
199 clock_t begin
= clock();
201 map
<string
,string
> args
;
204 for (count
=0; count
<argc
; count
++){
205 char *param
= argv
[count
];
206 char *str
= strchr(param
,'='); // Get value for param
208 int pos
= (int)(str
- param
); // Get position of "="
209 char *keybuf
= (char *)malloc(pos
-1 * sizeof(char));
210 strncpy(keybuf
, param
+ 1, (size_t)pos
-1); // Get key for param
211 keybuf
[pos
-1] = '\0';
212 args
[keybuf
] = str
+1;
219 args
["in"].c_str(), // Input file ( must be utf-8 )
220 args
["out"].c_str(), // Output file
221 stoi(args
["w"]), // Video width
222 stoi(args
["h"]), // Video height
223 args
["font"].c_str(), // Comment Font
224 stoi(args
["fontsize"]), // Font Size
225 stof(args
["alpha"]), // Comment Alpha
226 stof(args
["dm"]), // Duration of scrolling comment
227 stof(args
["ds"]) // Duration of still comment
230 clock_t end
= clock();
231 double elapsed_secs
= double(end
- begin
) / CLOCKS_PER_SEC
;
233 cout
<< "Exiting... Time taken:" << elapsed_secs
<< "s"<< endl
;