Форум программистов, компьютерный форум, киберфорум
Программирование Android
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/15: Рейтинг темы: голосов - 15, средняя оценка - 4.73
0 / 0 / 0
Регистрация: 15.01.2013
Сообщений: 3

ffmpeg Выдернуть кадр из видеофайла

15.01.2013, 05:29. Показов 3301. Ответов 2
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброго времени суток.
Бьюсь 4й день над проблемкой как при помощи ffmpeg выдернуть определенный кадр из видеофайла и передать его на сторону Java.
Вот что я сделал: Скомпилировал библиотеку ffmpeg, проверил на примерах все работает. Но вот пример как дернуть кадр из видео нашел лишь 1 вот тут.
Попробовал его у себя, получилось примерно следующее:
Код Библиотеки:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
#include <jni.h>
#include <android/log.h>
 
#include "libavutil/pixfmt.h"
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libswscale/swscale.h"
#include "cmdutils.h"
 
#define LOG_TAG "com.domain.tag"
#define LOGI(...)  __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...)  __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
 
const int ERROR_OPEN_FILE = -1;
const int ERROR_FIND_VIDEOSTREAM = -2;
const int ERROR_FIND_VIDEODECODER = -3;
const int ERROR_OPEN_VIDEODECODER = -4;
const int ERROR_NO_STREAM_INFO = -5;
 
typedef long thandle_file;
// Handle для файла - полная информация об открытом файле
struct thandle {
 AVFormatContext* ctx;
 AVCodecContext* codecCtx;
 int videoStream;
 AVPacket* packet;
} tHandle;
 
//отправляем в JAVA исключение с кодом errorCode
void make_exception(JNIEnv *env, int errorCode) {
 LOGI("exception %d", errorCode);
 char buffer[32];
 sprintf(buffer, "%d", errorCode);
 (*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/Exception"), buffer);
}
 
//инициализация
jint Java_ru_dzakhov_ffmpeg_test_FFMpegWrapper_initialize(JNIEnv *env) {
 av_register_all();
 LOGI("initialize_passed");
 return 0;
}
 
//определить размер кадра в формате Bitmap.Config.ARGB_8888
jint Java_ru_dzakhov_ffmpeg_test_FFMpegWrapper_getFrameBufferSize(JNIEnv *env, jobject thiz, thandle_file handleFile, jint width, jint height)
{
    return 0;
    }
//открыть файл, получить handle
jint Java_ru_dzakhov_ffmpeg_test_FFMpegWrapper_openFile(JNIEnv *env, jobject thiz, jstring fileName) {
AVFormatContext* ctx = 0;
const char *filename = (*env)->GetStringUTFChars(env, fileName, 0);
 
if(av_open_input_file(&ctx, filename, NULL, 0, NULL) != 0) {
  make_exception(env, ERROR_OPEN_FILE); //"Не удалось открыть видеофайл
  LOGI("not open");
}
 
// Retrieve stream information
if(av_find_stream_info(ctx)< 0) {
  make_exception(env, ERROR_NO_STREAM_INFO); //"Не удалось открыть видеофайл; // Couldn't find stream information
  LOGI("not open");
}
 
int videoStream = -1;
int i = 0;
for (i = 0; i < ctx->nb_streams; ++i) {
 if (ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
  videoStream = i;
  break;
 }
}
if (videoStream == -1) make_exception(env, ERROR_FIND_VIDEOSTREAM);
 
AVCodecContext* codecCtx = ctx->streams[videoStream]->codec;
AVCodec* codec = avcodec_find_decoder(codecCtx->codec_id);
 
if (codec == 0) {
 make_exception(env, ERROR_FIND_VIDEODECODER);
}
 
if (avcodec_open2(codecCtx, codec, 0) != 0) {
 make_exception(env, ERROR_OPEN_VIDEODECODER);
}
AVPacket* packet = (AVPacket*)malloc(sizeof(struct AVPacket));
av_init_packet(packet);
 
struct thandle* h = malloc(sizeof(struct thandle));
h->ctx = ctx;
h->codecCtx = codecCtx;
h->videoStream = videoStream;
h->packet = packet;
LOGI("openened");
//release java string
(*env)->ReleaseStringUTFChars(env, fileName, filename);
return (unsigned long)h;
}
 
//выдрать из открытого файла фрейм в формате Bitmap.Config.ARGB_8888
//в заданных размерах
//и сохранить битмапку в переданный Java объект java.nio.ByteBuffer
//время timeUS задается в микросекундах.
jint Java_ru_dzakhov_ffmpeg_test_FFMpegWrapper_getFrame(JNIEnv *env, jobject thiz, jstring fileName, jlong timeUS, jint width, jint height, jobject buffer) {
////////////////////////////////////////////////
    AVFormatContext* ctx = 0;
    const char *filename = (*env)->GetStringUTFChars(env, fileName, 0);
 
    if(av_open_input_file(&ctx, filename, NULL, 0, NULL) != 0) {
      make_exception(env, ERROR_OPEN_FILE); //"Не удалось открыть видеофайл
      LOGI("not open");
    }
 
    // Retrieve stream information
    if(av_find_stream_info(ctx)< 0) {
      make_exception(env, ERROR_NO_STREAM_INFO); //"Не удалось открыть видеофайл; // Couldn't find stream information
      LOGI("not open");
    }
 
    int videoStream = -1;
    int i = 0;
    for (i = 0; i < ctx->nb_streams; ++i) {
     if (ctx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
      videoStream = i;
      break;
     }
    }
    if (videoStream == -1) make_exception(env, ERROR_FIND_VIDEOSTREAM);
 
    AVCodecContext* codecCtx = ctx->streams[videoStream]->codec;
    AVCodec* codec = avcodec_find_decoder(codecCtx->codec_id);
 
    if (codec == 0) {
     make_exception(env, ERROR_FIND_VIDEODECODER);
    }
 
    if (avcodec_open2(codecCtx, codec, 0) != 0) {
     make_exception(env, ERROR_OPEN_VIDEODECODER);
    }
    AVPacket* packet = (AVPacket*)malloc(sizeof(struct AVPacket));
    av_init_packet(packet);
 
    struct thandle* h = malloc(sizeof(struct thandle));
    h->ctx = ctx;
    h->codecCtx = codecCtx;
    h->videoStream = videoStream;
    h->packet = packet;
    LOGI("openened");
    //release java string
    (*env)->ReleaseStringUTFChars(env, fileName, filename);
    //struct thandle* hf = (unsigned long)h;
    ///////////////////////////////////////////
//Функция для выдирания заданного фрейма из открытого файла
    LOGI("file= %d",h);
ctx = ((struct thandle*)h)->ctx;
codecCtx = ((struct thandle*)h)->codecCtx;
packet =  ((struct thandle*)h)->packet;
videoStream = ((struct thandle*)h)->videoStream;
long shortBuffer = buffer;
jshort* buff = (jshort*) (*env)->GetDirectBufferAddress(env, shortBuffer);
 
AVFrame* frame = avcodec_alloc_frame(); //YUV frame
avcodec_get_frame_defaults(frame);
 
//AV_TIME_BASE * time_in_seconds = avcodec_timestamp
//см. [url]http://dranger.com/ffmpeg/tutorial07.html[/url]
int frameNumber = timeUS;
int64_t pos = frameNumber * AV_TIME_BASE / 1000000;
int64_t seek_target= av_rescale_q(pos, AV_TIME_BASE_Q, ctx->streams[videoStream]->time_base);
//LOGI("seek_target= ");
//выполняем seek - попадаем на ближайший кейфрейм
//затем ищем нужный кадр.
int res = avformat_seek_file(ctx
 , videoStream
 , INT64_MIN
 , seek_target//* AV_TIME_BASE
 , INT64_MAX
 , 0);
LOGI("seek: %d f=%ld pos=%lld st=%lld", res, frameNumber, (int64_t)pos, seek_target);
if (res >= 0) {
 avcodec_flush_buffers(codecCtx);
 LOGI("flushed");
}
av_init_packet(packet);
 
AVFrame* frameRGB = avcodec_alloc_frame();
avcodec_get_frame_defaults(frameRGB);
 
enum PixelFormat pixel_format = PIX_FMT_RGBA;
avpicture_fill((AVPicture*) frameRGB
 , (uint8_t*)buff
 , pixel_format
 , width
 , height
);
 
while (av_read_frame(ctx, packet) == 0) {
 LOGI("pts=%lld st=%lld", packet->pts, seek_target);
 if (packet->stream_index == videoStream) {
  int gotPicture = 0;
  int bytesDecompressed = avcodec_decode_video2(codecCtx, frame, &gotPicture, packet);
    if (gotPicture && packet->pts >= seek_target) {
        LOGI("opana");
    // конвертируем данные из формата YUV в RGB24
    struct SwsContext* scaleCtx = sws_getContext(frame->width,
      frame->height,
      (enum PixelFormat)frame->format
      , width //frame->width,
      , height //frame->height,
      , pixel_format
      , SWS_BICUBIC
      , 0, 0, 0);
 
    int height = sws_scale(scaleCtx
      , frame->data
      , frame->linesize
      , 0
      , frame->height
      , frameRGB->data
      , frameRGB->linesize);
   break;
   }
  av_free_packet(packet);
  }
}
LOGI("ended");
av_free(frameRGB);
av_free(frame);
return 0;
}
 
 
jint Java_ru_dzakhov_ffmpeg_test_FFMpegWrapper_logFileInfo(JNIEnv * env, jobject this, jstring filename)
{
    av_register_all();
 
    AVFormatContext *pFormatCtx;
    const jbyte *str;
    str = (*env)->GetStringUTFChars(env, filename, NULL);
 
    if(av_open_input_file(&pFormatCtx, str, NULL, 0, NULL)!=0)
    {
        LOGE("Can't open file '%s'\n", str);
        return 1;
    }
    else
    {
        LOGI("File was opened\n");
        LOGI("File '%s', Codec %s",
            pFormatCtx->filename,
            pFormatCtx->iformat->name
        );
    }
    return 0;
}
 
jobject Java_ru_dzakhov_ffmpeg_test_FFMpegWrapper_allocNative(JNIEnv* env, jobject thiz, jlong size)
{
     void* buffer = malloc(size);
        jobject directBuffer = (*env)->NewDirectByteBuffer(env,buffer, size);
        return directBuffer;
}
void Java_ru_dzakhov_ffmpeg_test_FFMpegWrapper_freeNative(JNIEnv* env, jobject thiz, jobject globalRef)
{
    void *buffer = (*env)->GetDirectBufferAddress(env, globalRef);
        free(buffer);
}
Код Java:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package ru.dzakhov.ffmpeg.test;
 
import java.nio.ByteBuffer;
import java.nio.ShortBuffer;
 
public class FFMpegWrapper {
    static {
        System.loadLibrary("mylib");
        initialize();
    } 
private static native int initialize();
public static native long openFile(String fileName);
public static native int getFrameBufferSize(long handleFile, int format, int width, int height);
public static native int getFrame(String fileName, long timeUS, int width, int height, java.nio.Buffer buffer);
public static native int logFileInfo(String filename);
/** Выделить нативный буфер заданного размера*/
public static native ByteBuffer allocNative(long bufferSize);
 
/** Освободить нативный буфер заданного размера*/
public static native void freeNative(ByteBuffer my_buffer);
 
}
и наконец мэйнактивити:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package ru.dzakhov.ffmpeg.test;
 
import java.nio.ByteBuffer;
import java.nio.ShortBuffer;
import java.nio.channels.ScatteringByteChannel;
 
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import ru.dzakhov.ffmpeg.test.FFMpegWrapper;
 
public class MainActivity extends Activity {
 
// private static native int logFileInfo(String filename);
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //FFMpegWrapper.openFile("/storage/sdcard0/Movies/cool.wmv");
        int width = 60;
        int height =39;
        long timeUS =1000;
        // = 1024;
        //ByteBuffer my_buffer = FFMpegWrapper.allocNative(bufferSize);//.asFloatBuffer();// asShortBuffer();
        long handle = FFMpegWrapper.openFile("/storage/sdcard0/Movies/126_3_17.avi");
        long bufferSize = 1024;//FFMpegWrapper.getFrameBufferSize(handle, Bitmap.Config.ARGB_8888.hashCode(), width, height);
        ByteBuffer my_buffer = FFMpegWrapper.allocNative(bufferSize);//.asShortBuffer();
        Log.i("ttag",toString().valueOf(handle));
        Log.i("ttag",toString().valueOf(my_buffer));
        //long ww = FFMpegWrapper.getFrameBufferSize(handle, RESULT_OK, 60, 39);
        //Log.i("ttag",toString().valueOf(ww));
        FFMpegWrapper.getFrame("/storage/sdcard0/Movies/126_3_17.avi", timeUS, width, height, my_buffer);
        //Bitmap dest = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        //Buffer buffer = null;
        //dest.copyPixelsFromBuffer(buffer);
        //Ура, мы получили в dest битмапку c извлеченным кадром :)
      FFMpegWrapper.logFileInfo("/storage/sdcard0/Movies/126_3_17.avi");
      FFMpegWrapper.freeNative(my_buffer);
    }
 
 
}
В общем суть в том что в функции getFrame что-то идет не так, подозреваю неправильно рассчитывается seek_target (он почемуто всегда равен нулю, какое бы время я не передавал в функцию)
и естественно программа вылетает в момент когда попадает вот сюда "if (gotPicture && packet->pts >= seek_target) {
"
Вот лог во время запуска программы:

01-15 13:07:30.490: D/dalvikvm(8440): Trying to load lib /data/data/ru.dzakhov.ffmpeg.test/lib/libmylib.so 0x41cb7df8
01-15 13:07:30.495: D/dalvikvm(8440): Added shared lib /data/data/ru.dzakhov.ffmpeg.test/lib/libmylib.so 0x41cb7df8
01-15 13:07:30.495: D/dalvikvm(8440): No JNI_OnLoad found in /data/data/ru.dzakhov.ffmpeg.test/lib/libmylib.so 0x41cb7df8, skipping init
01-15 13:07:30.495: I/com.domain.tag(8440): initialize_passed
01-15 13:07:30.540: I/com.domain.tag(8440): openened
01-15 13:07:30.540: I/ttag(8440): 3270391527096277528
01-15 13:07:30.540: I/ttag(8440): java.nio.ReadWriteDirectByteBuffer, status: capacity=1024 position=0 limit=1024
01-15 13:07:30.595: I/com.domain.tag(8440): openened
01-15 13:07:30.595: I/com.domain.tag(8440): file= 1089515320
01-15 13:07:30.595: I/com.domain.tag(8440): seek: 0 f=1000 pos=1000 st=0
01-15 13:07:30.595: I/com.domain.tag(8440): flushed
01-15 13:07:30.595: I/com.domain.tag(8440): pts=0 st=0
01-15 13:07:30.595: I/com.domain.tag(8440): pts=1024 st=0
01-15 13:07:30.595: I/com.domain.tag(8440): pts=2048 st=0
01-15 13:07:30.595: I/com.domain.tag(8440): pts=3072 st=0
01-15 13:07:30.595: I/com.domain.tag(8440): pts=4096 st=0
01-15 13:07:30.595: I/com.domain.tag(8440): pts=5120 st=0
01-15 13:07:30.595: I/com.domain.tag(8440): pts=6144 st=0
01-15 13:07:30.595: I/com.domain.tag(8440): pts=7168 st=0
01-15 13:07:30.595: I/com.domain.tag(8440): pts=8192 st=0
01-15 13:07:30.595: I/com.domain.tag(8440): pts=9216 st=0
01-15 13:07:30.600: I/com.domain.tag(8440): pts=10240 st=0
01-15 13:07:30.600: I/com.domain.tag(8440): pts=11264 st=0
01-15 13:07:30.600: I/com.domain.tag(8440): pts=12288 st=0
01-15 13:07:30.600: I/com.domain.tag(8440): pts=13312 st=0
01-15 13:07:30.600: I/com.domain.tag(8440): pts=14336 st=0
01-15 13:07:30.600: I/com.domain.tag(8440): pts=15360 st=0
01-15 13:07:30.600: I/com.domain.tag(8440): pts=16384 st=0
01-15 13:07:30.600: I/com.domain.tag(8440): pts=0 st=0
01-15 13:07:30.635: I/com.domain.tag(8440): opana
01-15 13:07:30.715: A/libc(8440): Fatal signal 11 (SIGSEGV) at 0x48258000 (code=2), thread 8440 (hov.ffmpeg.test)


Помогите плиз решить проблемку.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.01.2013, 05:29
Ответы с готовыми решениями:

Извлечь кадр из видеофайла
Здравствуйте! Есть ли библиотеки или утилиты, либо средства в Qt, для извлечения кадра из видеофайла с произвольного момента?...

Как получить первый кадр из видеофайла
Здравствуйте, уважаемые форумчане. Прошу помощи в решении такой задачи: Как получить первый кадр из видеофайла. Практически, вопрос решен...

Ffmpeg. ошибка с разделением видеофайла
Всем привет! Есть видеофайл длиной одна минута. Задача — вырезать из него последние десять секунд и сделать их отдельным файлом. ...

2
36 / 36 / 9
Регистрация: 13.07.2011
Сообщений: 95
05.02.2013, 17:25
Привет! Жуть как надо скомпилировать ffmpeg под Андроид)
Можешь дать ссылки на информацию, которой пользовался, а то все, что я находил мне не помогло(вероятно проблема в руках).
За одно у меня и проблема похожая... вместе разберемся.
И еще вопрос сколько весит приложение с ffmpeg?

По ссылке в топике, нашел все что надо)
0
1162 / 986 / 1
Регистрация: 28.06.2012
Сообщений: 3,462
05.02.2013, 17:53
похоже на проблему синхронизации потоков.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
05.02.2013, 17:53
Помогаю со студенческими работами здесь

Ffmpeg, вытащить ширину видеофайла в переменную
В script.bat, прописываю ffprobe -v 0 -select_streams v -print_format flat -show_streams video.mp4 Далее в командной строке запускаю...

C++ builder + ffmpeg: вывести кадр на TImage
я получаю кадр от ffmpeg в формате AVFrame. как вывести кадр на TImage ?

Создание видеофайла из Bitmap-ов или разложение видеофайла на Bitmap-ы
1)Вопрос такой Есть Видео! как его программно разбить на bitmap-ы! 2)Вопрос как сделать видео файл из bitmap-ов! Зарание спасибо! ...

Открытие видеофайла
Весь трабл в том, собственно, что с видео работать близко вообще не приходилось. Видео было снято на фотоаппарат. формат стоит .avi, но...

Узнать продолжительность видеофайла
Как узнать продолжительность видеофайла? И тут же как сделать скриншот кадра на среднем значении по продолжительности видеофайла?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru