Я хочу сохранить видео в базе данных sqlite. P.S. Я не хочу хранить путь, а фактическое содержимое видео. Я преобразовал видео в массив байтов и сохранил массив байтов в базе данных sqlite. После извлечения bytearray преобразуется в файл. Но видео не воспроизводится. Пожалуйста помоги.
Может быть, тогда я смогу дать вам хороший ответ на это
тогда каким должен быть подход? Если я сохраню видео во внутреннем/внешнем хранилище и вместо этого сохраню путь, то как я смогу получить к нему доступ с какого-либо другого устройства. Кроме того, если мое устройство будет отформатировано, я потеряю все данные.
как прикрепить мой код? Когда я копирую и вставляю код, он не позволяет мне вставлять то же самое, поскольку помечает много ошибок.
Курсор SQLite имеет ограничение по размеру в 1 МБ. Таким образом, вы не можете хранить видео в SQLite.
это плохая идея
Вы можете использовать этот подход
При сохранении видео сохраните его в папке личного хранилища приложения.
Context.getFilesDir()
Это даст вам путь к хранилищу приложений в ..\Andorid\data\data\com.example.app
и он будет во внутренней памяти.
Где com.example.app будет вашим идентификатором пакета приложения. Вы можете создать новую папку здесь, например Videos, а затем сохранять видео в этой папке. Сохраните его путь в БД. Только ваше приложение может получить доступ к этой папке. Ни одно другое приложение или пользователь устройства не может получить доступ к этой папке. Таким образом, никто не может редактировать или удалять ваши файлы, кроме вашего приложения.
Более того, если пользователь сбросит мобильное устройство, эти данные будут удалены, а также ваша база данных и, возможно, ваше приложение в некоторых случаях. Поэтому не нужно беспокоиться о том, что ваши файлы будут удалены, но в базе данных все еще есть их путь. Если файл удален, то БД тоже удаляется, но только когда приложение Uninstall, device reset или SD card erase.
Код для загрузки видео, снятого через мое приложение на сервере sql? Мы должны преобразовать его в массив байтов и загрузить то же самое на сервер с помощью Volley или каким должен быть подход?
Вы можете легко найти код, как преобразовать видео в массив байтов в Интернете. И всякий раз, когда вы хотите загрузить видео на сервер, конвертируйте его непосредственно перед отправкой.
I want to store a video in sqlite database. P.S. I do not want to store the path but the actual video contents.
Если видео не очень короткие и не занимают мало места (скажем, до 200 КБ каждое, возможно, 1/10 секунды, но это зависит от формата, в котором оно сохранено), вы, вероятно, столкнетесь с проблемами и исключениями / сбоями.
Хотя SQLite имеет возможность хранить относительно большие BLOB в соответствии с: -
Maximum length of a string or BLOB
The maximum number of bytes in a string or BLOB in SQLite is defined by the preprocessor macro SQLITE_MAX_LENGTH. The default value of this macro is 1 billion (1 thousand million or 1,000,000,000). You can raise or lower this value at compile-time using a command-line option like this:
-DSQLITE_MAX_LENGTH=123456789 The current implementation will only support a string or BLOB length up to 231-1 or 2147483647. And some built-in functions such as hex() might fail well before that point. In security-sensitive applications it is best not to try to increase the maximum string and blob length. In fact, you might do well to lower the maximum string and blob length to something more in the range of a few million if that is possible.
During part of SQLite's INSERT and SELECT processing, the complete content of each row in the database is encoded as a single BLOB. So the SQLITE_MAX_LENGTH parameter also determines the maximum number of bytes in a row.
The maximum string or BLOB length can be lowered at run-time using the sqlite3_limit(db,SQLITE_LIMIT_LENGTH,size) interface. Limits In SQLite
КурсорОкно Android SDK имеет ограничение в 2 МБ, и это касается всех столбцов строк (строк) if buffers. Таким образом, даже если вы можете успешно сохранить видео, вы не сможете получить эти видео.
Рекомендуемый способ - это то, что вам не нужно, то есть сохранение пути к видео.
If i store the video in my internal/external storage and store the path instead then how will i be able to access the same from some other device.
У вас будет такая же проблема с базой данных, поскольку он обычно хранится в защищенных данных приложений. Это если база данных не является уже существующей базой данных (то есть заполненной данными), и в этом случае база данных распространяется с приложением через APK.
Если последнее — уже существующая база данных, распространяемая через APK, то видео также можно распространять как часть APK и, следовательно, так же защищено и доступно, как и база данных.
Если вы намерены распространять видео между устройствами, которые не являются частью APK, то SQlite, вероятно, не является правильным решением, поскольку это встроенная база данных и не имеет встроенных функций клиент/сервер.
Besides what if my device gets formatted then I will lose all the data.
В таком сценарии база данных будет так же уязвима, как и любые другие данные, так как это вся база данных, файл, такой же, как видео, текстовый документ и т. д., для которых требуется подходящее приложение для просмотра/изменения содержимого. Однако, если база данных уже существует, то простая переустановка приложения восстановит базу данных и другие файлы из APK.
После создания нового проекта 4 видео были загружены и скопированы в папку res/raw (после создания папки raw) в соответствии с: -
Помощник по базе данных (подкласс SQLiteOpenHelper) был создан для таблицы из 2 столбцов с - Столбец _я бы (примечание с именем _я бы для использования с SimpleCursorAdapter). - video_path для хранения пути/имени видео (не полный путь, но достаточный, чтобы можно было определить путь из сохраненных данных) - Обратите внимание, что код UNIQUE предотвращает добавление дубликатов.
С помощью некоторого базового метода, позволяющего добавлять и удалять строки и извлекать все строки (через Cursor для использования с SimpleCursorAdapter).
public class DBHelper extends SQLiteOpenHelper {
public static final String DBNAME = "myvideos";
public static final int DBVERSION = 1;
public static final String TBL_VIDEO = "video";
public static final String COL_VIDEO_ID = BaseColumns._ID;
public static final String COL_VIDEO_PATH = "video_path";
SQLiteDatabase mDB;
public DBHelper(Context context) {
super(context, DBNAME, null, DBVERSION);
mDB = this.getWritableDatabase();
}
@Override
public void onCreate(SQLiteDatabase db) {
String crt_video_table = "CREATE TABLE IF NOT EXISTS " + TBL_VIDEO + "(" +
COL_VIDEO_ID + " INTEGER PRIMARY KEY," +
COL_VIDEO_PATH + " TEXT UNIQUE" +
")";
db.execSQL(crt_video_table);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
public long addVideo(String path) {
ContentValues cv = new ContentValues();
cv.put(COL_VIDEO_PATH,path);
return mDB.insert(TBL_VIDEO,null,cv);
}
public Cursor getVideos() {
return mDB.query(TBL_VIDEO,null,null,null,null,null,null);
}
public int deleteVideoFromDB(long id) {
String whereclause = COL_VIDEO_ID + "=?";
String[] whereargs = new String[]{String.valueOf(id)};
return mDB.delete(TBL_VIDEO,whereclause,whereargs);
}
}
Довольно прямолинейный MainActivity.java (см. комментарии)
public class MainActivity extends AppCompatActivity {
TextView mMyTextView;
ListView mVideoList;
VideoView mVideoViewer;
DBHelper mDBHlpr;
Cursor mCsr;
SimpleCursorAdapter mSCA;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMyTextView = this.findViewById(R.id.mytext);
mVideoList = this.findViewById(R.id.videolist);
mVideoViewer = this.findViewById(R.id.videoviewer);
mDBHlpr = new DBHelper(this);
addVideosFromRawResourceToDB();
}
@Override
protected void onDestroy() {
mCsr.close(); //<<<<<<<<<< clear up the Cursor
super.onDestroy();
}
@Override
protected void onResume() {
super.onResume();
manageListView(); //<<<<<<<<<< rebuild and redisplay the List of Videos (in case they have changed)
}
/**
* Setup or Refresh the ListView adding the OnItemClick and OnItemLongClick listeners
*/
private void manageListView() {
mCsr = mDBHlpr.getVideos();
// Not setup so set it up
if (mSCA == null) {
// Instantiate the SimpleCursorAdapter
mSCA = new SimpleCursorAdapter(
this,
android.R.layout.simple_list_item_1, // Use stock layout
mCsr, // The Cursor with the list of videos
new String[]{DBHelper.COL_VIDEO_PATH}, // the column (columns)
new int[]{android.R.id.text1}, // the view id(s) into which the column(s) data will be placed
0
);
mVideoList.setAdapter(mSCA); // Set the adpater for the ListView
/**
* Add The Long Click Listener (will delete the video row from the DB (NOT the video))
*/
mVideoList.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
mDBHlpr.deleteVideoFromDB(id);
manageListView(); // <<<<<<<<<< refresh the ListView as data has changed
return true;
}
});
/**
* Play the respective video when the item is clicked
* Note Cursor should be at the correct position so data can be extracted directly from the Cursor
*/
mVideoList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
setCurrentVideo(mCsr.getString(mCsr.getColumnIndex(DBHelper.COL_VIDEO_PATH)));
}
});
} else {
mSCA.swapCursor(mCsr); //<<<<<<<<<< apply the changed Cursor
}
}
/**
* Set the currrent video and play it
* @param path the path (resource name of the video)
*/
private void setCurrentVideo(String path) {
mVideoViewer.setVideoURI(
Uri.parse(
"android.resource://" + getPackageName() + "/" + String.valueOf(
getResources().getIdentifier(
path,
"raw",
getPackageName())
)
)
);
mVideoViewer.start();
}
/**
* Look at all the resources in the res/raw folder and add the to the DB (not if they are duplicates due to UNQIUE)
*/
private void addVideosFromRawResourceToDB() {
Field[] fields=R.raw.class.getFields();
for(int count=0; count < fields.length; count++){
Log.i("Raw Asset: ", fields[count].getName());
mDBHlpr.addVideo(fields[count].getName());
}
}
}
Это абсолютно неправильно. Вы не можете сохранить его в БД. Если вы добавите 2 3 записи, вы не сможете запрашивать в БД после этого. Почему ты хочешь этого?