Skip to content

Instantly share code, notes, and snippets.

@ayutaz
Created February 12, 2020 22:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ayutaz/4366fc529a5d83f547c5f9008aed9c8b to your computer and use it in GitHub Desktop.
Save ayutaz/4366fc529a5d83f547c5f9008aed9c8b to your computer and use it in GitHub Desktop.
SoundLibraryのコード
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<!-- Semantic UI を読み込む -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/semantic-ui-css@2.4.1/semantic.min.css">
<link rel="stylesheet" href="main.css">
<script src="https://maps.googleapis.com/maps/api/js?key=<your google maps key>"></script>
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/7.6.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.6.1/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.6.1/firebase-database.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.6.1/firebase-storage.js"></script>
<!-- 音を再生するためのもの -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.1.2/howler.min.js"></script>
<title>音源ライブラリ</title>
</head>
<body>
<div class="ui main continer">
<div id="app">
<div id="map"></div>
<div class="ui two item pointing menu">
<a class="item" v-bind:class="{active:is_active.index}" v-on:click="makeActive('index')">一覧</a>
<a class="item" v-bind:class="{active:is_active.add}" v-on:click="makeActive('add')">追加</a>
</div>
<div v-if="active_item === 'index'">
<table class="ui celled table">
<thead>
<tr>
<th><i class="file image icon"></i>イメージ画像</th>
<th><i class="building icon"></i>場所の名前</th>
<th><i class="home icon"></i>住所</th>
<th><i class="calendar icon"></i>追加日時</th>
<th>音源再生・再生終了</th>
<th><i class="trash alternate icon"></i>削除</th>
</tr>
</thead>
<tbody>
<tr v-for="(item, key) in datas">
<td>
<a :href=item.image_url.i class="luminous" target="_blank">
<img :src=item.image_url.i widtzh="50" height="50">
</a>
</td>
<td>{{item.place}}</td>
<td>{{item.address}}</td>
<td>{{item.date.year}}年{{item.date.month}}月{{item.date.day}}日</td>
<td>
<button class="ui big button" v-on:click="music_play(item.audio_url.i)">
<i class="play icon"></i>
PLAY
</button>
<button class="ui big button" v-on:click="music_stop()">
<i class="stop icon"></i>
STOP
</button>
</td>
<td><button class="ui big negative button" v-on:click="remove_data(item.id)">削除</button></td>
</tr>
</tbody>
</table>
</div>
<div v-else-if="active_item === 'add'">
<div class="ui grid">
<div class="four wide column">
<div class="ui form error error_message">
<div class="ui error message" v-if="new_data.place == null || new_data.place == ''">
場所が記入されていません
</div>
</div>
<div class="ui form error error_message">
<div class="ui error message" v-if="new_data.address == null || new_data.address == ''">
住所が記入されていません
</div>
</div>
<div class="ui form error error_message">
<div class="ui error message" v-if="new_data.audio == null || new_data.audio == ''">
音声ファイルが選択されていません
</div>
</div>
<div class="ui form error error_message">
<div class="ui error message" v-if="new_data.image == null || new_data.image == ''">
画像ファイルが選択されていません
</div>
</div>
<div class="ui form error error_message">
<div class="ui error message" v-if="!new_data.lat && !new_data.lng">
<p>経緯度が入力されていません</p>
</div>
<div class="ui error message" v-else-if="!new_data.lat">
<p>経度が入力されていません</p>
</div>
<div class="ui error message" v-else-if="!new_data.lng">
<p>緯度が入力されていません</p>
</div>
</div>
</div>
<div class="eight wide column">
<div class="ui form">
<div class="field">
<label>場所</label>
<input type="text" v-model="new_data.place" placeholder="山梨大学">
</div>
<div class="field">
<label>住所</label>
<input type="text" v-model="new_data.address" placeholder="山梨県甲府市武田4丁目4−37">
</div>
<div class="field">
<label>音声ファイル名</label>
<input type="file" @change="select_audio">
</div>
<div class="field">
<label>画像ファイル名</label>
<input type="file" @change="select_image">
</div>
<div class="field">
<div class="two fields">
<div class="field">
<label>緯度</label>
<input type="text" v-model="new_data.lat" placeholder="35.66667">
</div>
<div class="field">
<label>経度</label>
<input type="text" v-model="new_data.lng" placeholder="139.6983773">
</div>
</div>
</div>
<div class="ui center aligned grid">
<div class="eight wide column">
<button class="ui huge positive button" v-on:click="add_data(new_data)">追加</button>
</div>
</div>
</div>
</div>
<div class="four wide column"></div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="./config.js"></script>
<script src="./main.js"></script>
</body>
</html>
#map{
height: 400px;
width: 100%;
}
*{
font-weight: bold;
}
.error_message{
height: 74px !important;
}
.four.wide.column{
margin-top: 23px !important;
}
new Vue({
el: "#app",
data: {
datas: [],
test: null,
firebaseRef: null,
fire_storage: null,
active_item: "index",
is_active: {
index: true,
add: false
},
new_data: {
place: null,
address: null,
audio: null,
lat: null,
lng: null,
// image: null,
image_path: null,
audio_path: null,
now: {
year: null,
month: null,
day: null
}
},
audio_datas: {
audio_id: null,
sound: null
}
},
created() {
this.initFirebase();
},
mounted: function () {
},
methods: {
// データを追加する
add_data: function (data) {
if (this.isValid(data)) {
let now = new Date();
firebase
.database()
.ref("/")
.push({
place: data.place,
lat: Number(data.lat),
lng: Number(data.lng),
image: 'image/yamanashi_univesity.jpg',
// audio:data.audio_path,
address:data.address,
date: {
year: now.getFullYear(),
month: now.getMonth() + 1,
day: now.getDate()
}
});
this.upload();
this.new_data.place = null;
this.new_data.audio = null;
this.new_data.lat = null;
this.new_data.lng = null;
this.new_data.image = null;
this.new_data.image_path = null;
this.new_data.audio_path = null;
}
},
remove_data: function (key) {
this.firebaseRef.child(key).remove();
},
makeActive: function (item) {
this.is_active.index = !this.is_active.index;
this.is_active.add = !this.is_active.add;
this.active_item = item;
},
initFirebase: function () {
firebase.initializeApp(firebaseConfig);
this.firebaseRef = firebase.database().ref("/");
this.fire_storage = firebase.storage().ref();
this.firebaseRef.on("value", snapshot => {
if (snapshot) {
const rootList = snapshot.val();
let list = [];
Object.keys(rootList).forEach((val, key) => {
rootList[val].id = val;
list.push(rootList[val]);
});
this.datas = list;
this.get_url(this.datas);
this.initMap(this.datas);
}
});
},
// マップを生成する
initMap: function (dataList) {
let location = new google.maps.LatLng({
lat: dataList[0].lat,
lng: dataList[0].lng
});
let map = new google.maps.Map(document.getElementById("map"), {
center: location,
zoom: 11,
fullscreenControl: false //フルスクリーンの拒否
});
google.maps.event.addListener(map, "click", this.getPosition);
for (let i = 0; i < dataList.length; i++) {
let location = new google.maps.LatLng({
lat: dataList[i].lat,
lng: dataList[i].lng
});
let marker = new google.maps.Marker({
// マーカーの追加
position: location, // マーカーを立てる位置を指定
map: map // マーカーを立てる地図を指定
});
let info_window = new google.maps.InfoWindow({
// 吹き出しの追加
content: dataList[i].place
});
info_window.open(map, marker);
}
},
music_play: function (url) {
if (this.audio_datas.audio_id != null) {
this.music_stop();
}
this.audio_datas.sound = new Howl({
src: url
});
this.audio_datas.audio_id = this.audio_datas.sound.play();
},
music_stop: function () {
this.audio_datas.sound.stop(this.audio_datas.audio_id);
},
upload: function () {
// let storage_image = this.fire_storage.child('image/kofu_station.jpeg');
// let storage_audio = this.fire_storage.child(this.new_data.audio.name);
// storage_audio.put(this.audio);
// storage_image.put(this.image).then(function (snapshot) {
// console.log("upload the image and audio");
// });
},
select_image: function (e) {
e.preventDefault();
this.new_data.image = e.target.files[0];
// this.new_data.image_path = this.new_data.image.fullPath;
},
select_audio: function (e) {
e.preventDefault();
this.new_data.audio = e.target.files[0];
},
isValid: function (data) {
if (data.place == null || data.place == '') return false;
else if (data.address == null || data.address == '') return false;
else if (data.audio == null || data.audio == '') return false;
else if (data.image == null || data.image == '') return falsel
else if (data.lat == null || data.lat == '') return false;
else if (data.lng == null || data.lng == '') return false;
else return true;
},
get_url: function (db_datas) {
for (var i = 0; i < db_datas.length; i++) {
console.log
this.$set(
db_datas[i],
"image_url",
this.fire_storage.child(db_datas[i].image).getDownloadURL()
);
// this.$set(
// db_datas[i],
// "audio_url",
// this.fire_storage.child(db_datas[i].audio).getDownloadURL()
// );
}
},
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment