Show list of all videos from internal storage - flutter

list all video files from a specific folder from internal storage and display them in flutter.
i want to create an app to list all videos in internal storage and show them in gridview and play that video

To get all the files from the storage you can use path_provider flutter package. With this, get the folder path, extract all the files with an extension of .mp4 (video file), and store it in List.
List<FileSystemEntity> _files = [];
void _getFiles() async {
Directory directory = await getExternalStorageDirectory();
List<FileSystemEntity> files = directory.listSync().where((entity) => entity.path.endsWith('.mp4')).toList();
setState(() {
_files = files;
});
}
Then you can use video_player Flutter package to play the video.
GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
childAspectRatio: 1,
),
itemCount: _files.length,
itemBuilder: (BuildContext context, int index) {
return GestureDetector(
onTap: () {
setState(() {
_controller = VideoPlayerController.file(_files[index])
..initialize().then((_) {
_controller.play();
});
});
},
child: Card(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(
Icons.video_library,
size: 50,
),
SizedBox(height: 10),
Text(_files[index].path.split('/').last),
],
),
),
);
},
);

Related

flutter: just_audio player plugin seekToNext and seekToPrevious

Im new to flutter and Im creating a music player using just_audio plugin but I having trouble implementing the nxt button where I want to change the song that currently playing.
ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount: item.data!.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(item.data![index].title),
trailing: IconButton(
icon: const Icon(Icons.play_arrow),
onPressed: () {
playmusichandler('${item.data![index].uri}');
},
),
t
void playmusic() async{
try {
await widget.audioPlayer
.setAudioSource(AudioSource.uri(Uri.parse(widget.songModel.uri!)));
await widget.audioPlayer.play();
} catch (e) {
debugPrint('$e');
}
}
==
StreamBuilder<SequenceState?>(
stream: widget.audioPlayer.sequenceStateStream,
builder: (context, index) {
return IconButton(
onPressed: () {
widget.audioPlayer.hasNext
? widget.audioPlayer.seekToNext()
: null;
},
icon: const Icon(
Icons.skip_next,
size: 45.0,
color: Colors.white,
));
}),
It is important to note that here you are working with audio clips which means you are using single songs. Nevertheless, a playlist is another option available in the just_audio package.
Working with gapless playlists.
`// Define the playlist
final playlist = ConcatenatingAudioSource(
// Start loading next item just before reaching it
useLazyPreparation: true,
// Customise the shuffle algorithm
shuffleOrder: DefaultShuffleOrder(),
// Specify the playlist items
children: [
AudioSource.uri(Uri.parse('https://example.com/track1.mp3')),
AudioSource.uri(Uri.parse('https://example.com/track2.mp3')),
AudioSource.uri(Uri.parse('https://example.com/track3.mp3')),
],
);
// Load and play the playlist
await player.setAudioSource(playlist, initialIndex: 0, initialPosition: Duration.zero);
await player.seekToNext(); // Skip to the next item
await player.seekToPrevious(); // Skip to the previous item
await player.seek(Duration.zero, index: 2); // Skip to the start of track3.mp3
await player.setLoopMode(LoopMode.all); // Set playlist to loop (off|all|one)
await player.setShuffleModeEnabled(true); // Shuffle playlist order (true|false)
// Update the playlist
await playlist.add(newChild1);
await playlist.insert(3, newChild2);
await playlist.removeAt(3);`
When you are dealing with children, you have to pass the audio list to them. Following that, you can use the index to determine which song will play when you select a song, then you can choose to play previous or other options

how to show circular progress indicator while uploading multiple images to firebase using two screens

i am making a house management app i have to upload images of the property alongside other data related to the property so i am using two screens one for the general info about the house and the second one specifically to upload images
Form screen
Image Upload Screen
from the upload screen i am returning back a list of images to the form screen
// i am waiting for the list in the form screen
images = await Navigator.push(context, MaterialPageRoute(builder: (context) => AddPictures()));
// i am returning the list back from the upload screen
Navigator.pop(context,imageStrings);
I am failing to show circular progress indicator for some reason beyond my capacity to know itried all ways i know
this is the rest of the code
//outiside the widdget build i have two lists
List<XFile> imagesXFiles = []; //for raw image files from the gallery or camera
List<String> imageStrings = []; //for image links from the firebase storage
body: isLoading == true ? CircularProgressIndicator() : Column(
children: [
Expanded(
//the first grid is a button to let the user access camera or gallery
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 2.0,
mainAxisSpacing: 2.0
),
itemCount: imagesXFiles.length + 1,
itemBuilder: (BuildContext context, int index) {
return index == 0 ? GestureDetector(
onTap: (){
// a function to pick images and add store them to the list "imagesXFiles"
_showPicker(context);
},
child: Container(
decoration: BoxDecoration(
color: Colors.black12,
borderRadius: BorderRadius.circular(5.0),
),
child: Icon(
Icons.add,
color: Colors.black,
size: 30.0,
),
),
): Container(
child: Image(
image: FileImage(File(imagesXFiles[index-1].path)),
fit: BoxFit.fill
),
);
},
),
),
TextButton(
onPressed: ()async{
// for some reason the circular progress doesn't work i dont understand why
setState(() {
isLoading = true;
});
imageStrings = await uploadImages(imagesXFiles).whenComplete(() {
setState(() {
isLoading = false;
Navigator.pop(context,imageStrings);
});
});
},
child: Text("Upload",style: TextStyle(color: Colors.black,fontSize: 25),)),
],
),
here is the upload function that uploads the images to firebase
Future<List<String>> uploadImages(List<XFile> imagesXFiles) async {
imagesXFiles.forEach((image) async {
final storageRef = storage.ref().child(Random().nextInt(100).toString());
await storageRef.putFile(File(image.path));
String imageURL = await storageRef.getDownloadURL();
imageStrings.add(imageURL);
firebaseFirestore
.collection("housePictures")
.add({
"imageURL" : imageURL,
});
});
return imageStrings;
}
You can use forEach with Future as below.
await Future.forEach(imagesXFiles, (image) async {
final storageRef = storage.ref().child(Random().nextInt(100).toString());
await storageRef.putFile(File(image.path));
String imageURL = await storageRef.getDownloadURL();
imageStrings.add(imageURL);
FirebaseFirestore.instance
.collection("housePictures")
.add({
"imageURL" : imageURL,
});
});
You can’t use forEach statement in an async operation. It is not going to wait. Use a normal for statement. Example: for(var item in items) etc. That should fix your issue. If you really want to use a for each you need to use Future. foreach see this thread -> How to Async/await in List.forEach() in Dart

Flutter Firebase Storage Data doesn't show Data immediately

I'm currently working on a project in flutter where I want to store uploaded Data in Firebase Storage. This works fine but now I'm facing a problem with showing the data. I have to do a restart for showing the uploaded Data in my List.
I hope someone can help me with this issue.
onPressed: () async {
FilePickerResult? result = await FilePicker.platform
.pickFiles(allowMultiple: true);
if (result == null) return;
final path = result.files.single.path!;
setState(() {
});
final fileName = result.files.single.name;
storage
.uploadFile(path, fileName)
.then((value) => print('Done'));
},
This is my call function when pressing the button.
Future<void> uploadFile(String destination, String fileName) async {
final User? user = auth.currentUser;
final uid = user!.uid;
File file = File(destination);
try {
await storage.ref('$uid/$fileName').putFile(file);
} on firebase_core.FirebaseException catch (e) {
print(e);
}
}
This is my method for pushing the data into firebase storage.
Container(
width: MediaQuery.of(context).size.width - 15,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25),
),
child: FutureBuilder(
future: _loadImages(),
builder: (context,
AsyncSnapshot<List<Map<String, dynamic>>> snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return Row(
children: [
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: snapshot.data?.length ?? 0,
itemBuilder: (context, index) {
final Map<String, dynamic> image =
snapshot.data![index];
return Card(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.circular(20)),
elevation: 0,
child: ListTile(
dense: false,
contentPadding: EdgeInsets.all(15),
leading: Image.network(
image['url'],
),
trailing: IconButton(
onPressed: () => _delete(image['path']),
icon: const Icon(
Icons.delete,
color: Colors.red,
),
),
),
);
},
),
),
],
);
}
return const Center(
child: CircularProgressIndicator(),
);
},
),
),
And this is how I display my files in my app.
Looking forward for some help.
I want to see my data directly when uploading it into Firebase Storage.
If you want to show the newly uploaded image right away, you will have to force a refresh of the code that renders the list of images. If you're using a StatefulWidget to render the images, you could for example call setState() on that widget after the upload has completed. If you're using another state management approach, you'd do the equivalent for that approach.
But note that this will only work on the device of the user who uploaded the image. Any other devices will still only see the new image if they manually restart the rendering of the list of images.
A common way to work around this is to store the list of image URLs in one of Firebase's databases (Realtime Database or Cloud Firestore), and render it from there with a StreamBuilder. The StreamBuilder continues to listen for updates to the database, so if one user's image upload completes and they write the URL/path of the image to the database, that immediately refreshes the list of images not just on their device, but on all other connected devices too.

display list of pdf and image separately from api in flutter

I want to display a list of images and pdf files that I am getting from API in response by separating them into PFD and image.
I have successfully displayed an images list that I am getting from API in circleAvatar using image.network, but now I am not getting the idea of how do I display a pdf list so that when I tap one pdf it opens in a viewer.
below is the image of how I want to display it in the list -:
the first blue circle is empty because it has a pdf path and the next has an image.
code for displaying the image and pdf file -
GridView.count(
crossAxisCount: 3,
children: List.generate(document?.length, (ind) {
return
Padding(
padding: const EdgeInsets.all(8.0),
child: CircleAvatar(
radius: 80,
backgroundImage:
NetworkImage('${api.getHTTPUri('/${document[ind].documentPath}')}'),
),
),
}),
),
you can use following package from pub.dev : flutter_pdfview
PDFView(
filePath: path,
enableSwipe: true,
swipeHorizontal: true,
autoSpacing: false,
pageFling: false,
onRender: (_pages) {
setState(() {
pages = _pages;
isReady = true;
});
},
onError: (error) {
print(error.toString());
},
onPageError: (page, error) {
print('$page: ${error.toString()}');
},
onViewCreated: (PDFViewController pdfViewController) {
_controller.complete(pdfViewController);
},
onPageChanged: (int page, int total) {
print('page change: $page/$total');
},
),
package link.
for list,
ListView.builder(
itemCount: length, //pass the length of list
itemBuilder: (context, index) {
return GestureDetector(
onTap: () {
//code for opening pdf goes here
},
child: Container(
color: Colors.grey.shade200,
margin: EdgeInsets.symmetric(
horizontal: 4, vertical: 8),
child: Row(children:[
//code of circle avatar
Text("//name of pdf at this index")])
),
);
},
),
link of tutorial for listview.builder

how to pick multiple images from gallery and store them in array in flutter?

i used image_picker package in my app and it works fine for one image but now i want to use it for multiple images and store them in an array as File. any idea could be greate.
Add dependecy of image_picker:
image_picker: ^0.8.4+3
Then make a method for selectImages():
final ImagePicker imagePicker = ImagePicker();
List<XFile>? imageFileList = [];
void selectImages() async {
final List<XFile>? selectedImages = await
imagePicker.pickMultiImage();
if (selectedImages!.isNotEmpty) {
imageFileList!.addAll(selectedImages);
}
print("Image List Length:" + imageFileList!.length.toString());
setState((){});
}
Create a builder for showing selected Images:
return Scaffold(
appBar: AppBar(
title: Text('Multiple Images'),
),
body: SafeArea(
child: Column(
children: [
ElevatedButton(
onPressed: () {
selectImages();
},
child: Text('Select Images'),
),
Expanded(
child: Padding(
padding: const EdgeInsets.all(8.0),
child: GridView.builder(
itemCount: imageFileList!.length,
gridDelegate:
SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3),
itemBuilder: (BuildContext context, int index) {
return Image.file(File(imageFileList![index].path),
fit: BoxFit.cover,);
}),
),
),
],
),
));
Complete Source code available in github link...
https://github.com/NishaJain24/multi_image_picker
you should use this
//add this to pubspec.yaml
multi_image_picker: ^4.7.14
//add those to the dart file
import 'package:flutter/material.dart';
import 'package:multi_image_picker/multi_image_picker.dart';
import 'dart:async';
//add a button then in onPressed do this
MultiImagePicker.pickImages(
maxImages: 300,
enableCamera: true,
selectedAssets: images,
materialOptions: MaterialOptions(
actionBarTitle: "FlutterCorner.com",
),
);
for further infos check this
https://medium.com/#fluttercorner/how-to-select-multiple-images-with-flutter-8fe8e4c78d08
The documentation covers that in here .
final List<XFile>? images = await _picker.pickMultiImage(source: ImageSource.gallery);
That saves it in a list of XFile. There are some platform specific implementation you have to go through so dont miss that. Just have a look at the documentation.